danstowell@0: danstowell@0: # utility functions danstowell@0: danstowell@0: import numpy as np danstowell@0: from numpy import float32 danstowell@0: danstowell@0: import os, errno danstowell@0: from scikits.audiolab import Sndfile danstowell@0: from scikits.audiolab import Format danstowell@0: danstowell@0: from matplotlib.mlab import specgram danstowell@0: danstowell@0: from userconfig import * danstowell@0: danstowell@0: ######################################################## danstowell@0: danstowell@0: def standard_specgram(signal): danstowell@0: "Return specgram matrix, made using the audio-layer config" danstowell@0: return np.array(specgram(signal, NFFT=audioframe_len, noverlap=audioframe_len-audioframe_stride, window=np.hamming(audioframe_len))[0][specbinlow:specbinlow+specbinnum,:], dtype=float32) danstowell@0: danstowell@0: def load_soundfile(inwavpath, startpossecs, maxdursecs=None): danstowell@0: """Loads audio data, optionally limiting to a specified start position and duration. danstowell@0: Must be SINGLE-CHANNEL and matching our desired sample-rate.""" danstowell@0: framelen = 4096 danstowell@0: hopspls = framelen danstowell@0: unhopspls = framelen - hopspls danstowell@0: if (framelen % wavdownsample) != 0: raise ValueError("framelen needs to be a multiple of wavdownsample: %i, %i" % (framelen, wavdownsample)) danstowell@0: if (hopspls % wavdownsample) != 0: raise ValueError("hopspls needs to be a multiple of wavdownsample: %i, %i" % (hopspls , wavdownsample)) danstowell@0: if maxdursecs==None: danstowell@0: maxdursecs = 9999 danstowell@0: sf = Sndfile(inwavpath, "r") danstowell@0: splsread = 0 danstowell@0: framesread = 0 danstowell@0: if sf.channels != 1: raise ValueError("Sound file %s has multiple channels (%i) - mono required." % (inwavpath, sf.channels)) danstowell@0: timemax_spls = int(maxdursecs * sf.samplerate) danstowell@0: if sf.samplerate != (srate * wavdownsample): danstowell@0: raise ValueError("Sample rate mismatch: we expect %g, file has %g" % (srate, sf.samplerate)) danstowell@0: if startpossecs > 0: danstowell@0: sf.seek(startpossecs * sf.samplerate) # note: returns IOError if beyond the end danstowell@0: audiodata = np.array([], dtype=np.float32) danstowell@0: while(True): danstowell@0: try: danstowell@0: if splsread==0: danstowell@0: chunk = sf.read_frames(framelen)[::wavdownsample] danstowell@0: splsread += framelen danstowell@0: else: danstowell@0: chunk = np.hstack((chunk[:unhopspls], sf.read_frames(hopspls)[::wavdownsample] )) danstowell@0: splsread += hopspls danstowell@0: framesread += 1 danstowell@0: if framesread % 25000 == 0: danstowell@0: print("Read %i frames" % framesread) danstowell@0: if len(chunk) != (framelen / wavdownsample): danstowell@0: print("Not read sufficient samples - returning") danstowell@0: break danstowell@0: chunk = np.array(chunk, dtype=np.float32) danstowell@0: audiodata = np.hstack((audiodata, chunk)) danstowell@0: if splsread >= timemax_spls: danstowell@0: break danstowell@0: except RuntimeError: danstowell@0: break danstowell@0: sf.close() danstowell@0: return audiodata danstowell@0: danstowell@0: def mkdir_p(path): danstowell@0: try: danstowell@0: os.makedirs(path) danstowell@0: except OSError as exc: # Python >2.5 danstowell@0: if exc.errno == errno.EEXIST and os.path.isdir(path): danstowell@0: pass danstowell@0: else: raise danstowell@0: