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 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