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)
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()
def __init__(self, configfile=None): self.spectrogram = spectrogram(configfile=configfile) self.readconfig(configfile) self.signal = None self.image = None self.Fs = None