Example #1
0
    def load_signal(self, locator, dtype='d'):
        """
        Loads the signal and computes the spectrogram.

        dtype: the data type to store the output in. Use
               single-precision floats if needed to reduce storage
               requirements.
        """
        from ewave import wavfile
        from libtfr import fgrid, dynamic_range
        from chirp.common.signal import spectrogram
        from chirp.common.geom import elementlist, masker
        from numpy import linspace, log10

        fp = wavfile(locator)
        signal = fp.read()
        Fs = fp.sampling_rate

        speccr = spectrogram(**self.options)
        # adjust window size to get correct number of frequency bands
        df = 1. * (self.options['freq_range'][1] - self.options['freq_range'][0]) / self.options['nfreq']
        nfft = int(Fs / df)

        spec, extent = speccr.linspect(signal, Fs / 1000, nfft=nfft)
        F, ind = fgrid(Fs, nfft, self.options['freq_range'])   # in Hz
        spec = spec[ind, :]
        T = linspace(extent[0], extent[1], spec.shape[1])      # in ms

        # first convert the spectrogram to its final scale
        if self.options['powscale'].startswith('log'):
            # TODO calculate dynamic range of the signal for non 16 bit PCM?
            spec = log10(dynamic_range(spec, 96))
            # recenter spectrogram
            if self.options['subtract_mean']:
                spec -= spec.mean()

        if self.options['mask'] != 'none':
            eblfile = os.path.splitext(locator)[0] + elementlist.default_extension
            if os.path.exists(eblfile):
                mask = elementlist.read(eblfile)
                spec = masker(boxmask=self.options['mask'] == 'box').cut(spec, mask, T, F / 1000.)

        return spec.astype(dtype)
Example #2
0
def cpitch(argv=None, cout=None, cerr=None, **kwargs):
    """ The script front-end """
    import sys
    from chirp.version import version
    if argv is None:
        argv = sys.argv[1:]
    if cout is None:
        cout = sys.stdout
    if cerr is None:
        cerr = sys.stderr

    import getopt
    from chirp.common.config import configoptions
    config = configoptions()

    maskfile = None

    opts, args = getopt.getopt(argv, 'hvc:m:')

    for o, a in opts:
        if o == '-h':
            print _scriptdoc
            return -1
        elif o == '-v':
            print "cpitch version %s" % version
            return -1
        elif o == '-c':
            if not os.path.exists(a):
                print >> cout, "ERROR: config file %s doesn't exist" % a
                return -1
            config.read(a)
        elif o == '-m':
            maskfile = a
    if len(args) < 1:
        print _scriptdoc
        return -1

    print >> cout, "* Program: cpitch"
    print >> cout, "** Version: %s" % version
    print >> cout, "* Input: %s" % args[0]

    from ewave import wavfile
    try:
        fp = wavfile(args[0])
    except IOError:
        print >> cerr, "No such file %s" % args[0]
        return -2
    except:
        print >> cerr, "Input file %s must be in WAV format" % args[0]
        return -2

    pcm = fp.read()
    samplerate = fp.sampling_rate / 1000.
    print >> cout, "** Samples:", pcm.size
    print >> cout, "** Samplerate: %.2f (kHz)" % samplerate

    pt = tracker(configfile=config, samplerate=samplerate * 1000, **kwargs)
    print >> cout, pt.spectrogram_options_str()
    print >> cout, pt.template_options_str()
    print >> cout, "* DLFT spectrogram:"
    spec, tgrid, fgrid = pt.matched_spectrogram(pcm, samplerate)
    print >> cout, "** Dimensions:", spec.shape

    print >> cout, pt.particle_options_str()

    if maskfile is not None and os.path.exists(maskfile):
        from chirp.common.geom import elementlist, masker
        print >> cout, "* Mask file:", maskfile
        elems = elementlist.read(maskfile)
        mask = masker(configfile=config, **kwargs)
        for startcol, mspec, imask in mask.split(spec, elems, tgrid, fgrid, cout=cout):
            try:
                startframe, pitch_mmse, pitch_var, pitch_map, stats = pt.track(mspec, cout=cout, mask=imask)
                stats['p.map'] = None if pitch_map is None else pitch_map * samplerate
                T = tgrid[startframe + startcol:startframe + startcol + pitch_mmse.shape[0]]
                # + tracker.options['winsize'] / (samplerate * 1000) ??
                ptrace = pitchtrace(T, pitch_mmse * samplerate, pitch_var * samplerate * samplerate,
                                    **stats)
                print >> cout, "*** Pitch calculations:"
                ptrace.write(cout)
            except ValueError, e:
                print >> cout, "*** Pitch calculation error: %s" % e
                continue