Пример #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)
Пример #2
0
def multiplotter(outfile, config, cout=None, show_pitch=True, pitchdir=None):
    """
    A coroutine for plotting a bunch of motifs on the same page. A
    useful entry point for scripts that want to do something similar
    to cplotpitch, but with control over which motifs get plotted.
    """
    matplotlib.use('PDF')
    from matplotlib.backends.backend_pdf import PdfPages as multipdf
    from matplotlib.pyplot import close as close_figure
    from chirp.version import version
    from chirp.common.graphics import axgriditer
    from chirp.common.signal import spectrogram

    def gridfun(**kwargs):
        from matplotlib.pyplot import subplots
        return subplots(_nrows, _ncols, sharex=True, sharey=True, figsize=_figsize)

    def figfun(fig):
        maxx = max(ax.dataLim.x1 for ax in fig.axes)
        ax = fig.axes[0]
        ax.set_xticklabels('')
        ax.set_yticklabels('')
        ax.set_xlim(0, maxx)
        for ax in fig.axes:
            ax.yaxis.set_ticks_position('left')
            ax.xaxis.set_ticks_position('bottom')
        fig.subplots_adjust(left=0.05, right=0.95, wspace=0)
        pp.savefig(fig)
        close_figure(fig)

    # set up plotting
    pp = multipdf(outfile)
    axg = axgriditer(gridfun, figfun)
    spectrogram = spectrogram(configfile=config)
    plt = plotter(configfile=config)

    filt = postfilter.pitchfilter(configfile=config)
    print >> cout, filt.options_str()

    print >> cout, "* Plotting signals:"
    try:
        # first call to yield won't return anything
        ax = None
        while 1:
            # receives filename from caller and returns last axes
            basename = yield ax
            ax = axg.next()

            try:
                signal, Fs, t, p = load_data(basename, filt, pitchdir)
                print >> cout, "** %s" % basename
            except Exception, e:
                print >> cout, "** %s: error loading data (%s)" % (basename, e)
                continue
            spec, extent = spectrogram.dbspect(signal, Fs)
            plt.plot_spectrogram(ax, spec, extent)
            if show_pitch and t is not None:
                plt.plot_trace(ax, t, p)

        # loop will break when caller sends stop()
    finally:
        axg.close()
        pp.close()
Пример #3
0
 def __init__(self, configfile=None):
     self.spectrogram = spectrogram(configfile=configfile)
     self.readconfig(configfile)
     self.signal = None
     self.image = None
     self.Fs = None