def calc_data(dirname, basename): search_filename = basename + '*.wav' filenames = glob.glob( os.path.join(dirname, search_filename)) filenames.sort() if defs.ONLY_N_FILES: filenames = filenames[:defs.ONLY_N_FILES] detected_freqs, adjusted_freqs, stats, final = estimate_f0_B.estimate_f0_B(filenames) f0 = final.f0 B = final.B decayss = [] for i, wav_filename in enumerate(filenames): print "Processing %s" % wav_filename plot = False decays = chemistry.calc_harmonics(wav_filename, f0, B, plot=plot) decayss.extend(decays) return decayss, f0, B
def calc_data(dirname, basename): search_filename = basename + '*.wav' filenames = glob.glob(os.path.join(dirname, search_filename)) filenames.sort() if defs.ONLY_N_FILES: filenames = filenames[:defs.ONLY_N_FILES] detected_freqs, adjusted_freqs, stats, final = estimate_f0_B.estimate_f0_B( filenames) f0 = final.f0 B = final.B decayss = [] for i, wav_filename in enumerate(filenames): print "Processing %s" % wav_filename plot = False decays = chemistry.calc_harmonics(wav_filename, f0, B, plot=plot) decayss.extend(decays) return decayss, f0, B
def get_harmonics(wav_filename, f0=None, B=None, limit=None, recalc=False): pickle_filename = wav_filename + ".stft.pickle" if os.path.exists(pickle_filename) and not recalc: print "Reading from", pickle_filename pickle_file = open(pickle_filename, 'rb') (harmonics, hop_rate) = pickle.load(pickle_file) pickle_file.close() else: if f0 is None: _, _, _, final = estimate_f0_B.estimate_f0_B( [wav_filename]) f0 = final.f0 B = final.B limit = final.highest_mode print "Using f0, B, limit:\t%.1f\t%.3g\t%i" % ( f0, B, limit) (harmonics, hop_rate) = calc_harmonics(wav_filename, f0, B, limit) pickle_file = open(pickle_filename, 'wb') pickle.dump( (harmonics, hop_rate), pickle_file, -1) pickle_file.close() print "Wrote to", pickle_filename return harmonics, hop_rate
def calc_harmonics(wav_filename, f_0=None, B=None, plot=False): wav_filename = os.path.realpath(os.path.expanduser(wav_filename)) if f_0 is None: detected_freqs, adjusted_freqs, stats, final = estimate_f0_B.estimate_f0_B( [wav_filename]) f_0 = final.f0 B = final.B print "Estimating f_0 and B from single file, but not good!" global fs global WINDOWSIZE fs, rawwav = scipy.io.wavfile.read(wav_filename) wav = rawwav / float(numpy.iinfo(rawwav.dtype).max) wav = truncate_to_maximum_length(wav, SECONDS_MAXIMUM * fs) wav = remove_DC_offset(wav) #print len(wav) wav = zero_pad_to_next_power_two(wav) #print len(wav) buf = wav ZERO_PADDING = 4 WINDOWSIZE = ZERO_PADDING * len(buf) fft = scipy.fftpack.fft(buf, WINDOWSIZE) fft_positive = abs(fft[0:len(fft)/2]) fft_normalized = fft_positive / float(WINDOWSIZE) fft_power = fft_normalized**2 #fft_examine = fft_normalized fft_examine = fft_power freqs = numpy.array( [ bin2hertz(i) for i, y in enumerate(fft_examine) ] ) if plot: pylab.figure() # avoid the 0 DC offset term pylab.plot( [ f for f, m in zip(freqs[1:], fft_examine[1:]) if m > 0.0], [ numpy.log(m) for f, m in zip(freqs[1:], fft_examine[1:]) if m > 0.0], ) pylab.title("Overall power\n%s" % (wav_filename)) #search_radius = defs.PEAK_SPREAD_HERTZ search_radius = defs.LONG_PEAK_AREA_HERTZ print "f_0: %.3f \t B: %.3g" % (f_0, B) decays = [] add_plot = plot plot = False for n in range(1,NODES_MAXIMUM+1): #if add_plot: if False: pylab.axvline( n*f_0, color="pink", #linewidth=3.0, alpha=0.8, label="ideal", ) pylab.axvline( mode_B2freq(f_0, n, B/4), color="purple", #linewidth=3.0, alpha=0.8, label="experimental B/4", ) freq_center = mode_B2freq(f_0, n, B) freq_low = freq_center - search_radius freq_high = freq_center + search_radius plot = False freq, alpha, rsquared, variance = fit_lorentzian( fft_examine, freq_low, freq_high, freq_center, plot=plot, add_plot=add_plot) if alpha == 0: continue w = 2*numpy.pi*freq Q = w / (2*alpha) drop = 0 decay = classes.Decay(freq, w, n, alpha, Q, rsquared, variance, drop) decays.append(decay) if add_plot: pylab.show() return decays
filenames = glob.glob(os.path.realpath(os.path.expanduser(dirname)) + '*.wav') filenames.sort() for i, wav_filename in enumerate(filenames): basename = os.path.basename(wav_filename) key = '-'.join(basename.split('-')[:-1]) inst_strings.setdefault(key, []).append(wav_filename) for key in sorted(inst_strings): #print '------', key filenames = inst_strings[key] filenames.sort() if defs.ONLY_N_FILES > 0: filenames = filenames[:defs.ONLY_N_FILES] f0, B, num_harmonics, rsquared = estimate_f0_B.estimate_f0_B(filenames) print "%s\t%.1f\t%.4e\t%i\t%.4e" % (key, f0, B, num_harmonics, rsquared) if defs.PLOT_B: pylab.show() exit(0) data_f0 = {} data_B = {} data_num = {} if PLOT_FREQS: pylab.figure() exit(0)
filenames = glob.glob( os.path.realpath(os.path.expanduser(dirname)) + '*.wav') filenames.sort() for i, wav_filename in enumerate(filenames): basename = os.path.basename(wav_filename) key = '-'.join(basename.split('-')[:-1]) inst_strings.setdefault(key, []).append(wav_filename) for key in sorted(inst_strings): #print '------', key filenames = inst_strings[key] filenames.sort() if defs.ONLY_N_FILES > 0: filenames = filenames[:defs.ONLY_N_FILES] f0, B, num_harmonics, rsquared = estimate_f0_B.estimate_f0_B(filenames) print "%s\t%.1f\t%.4e\t%i\t%.4e" % ( key, f0, B, num_harmonics, rsquared) if defs.PLOT_B: pylab.show() exit(0) data_f0 = {} data_B = {} data_num = {} if PLOT_FREQS: pylab.figure()
def generate_data(self, dirname, basename, plot_harms=False): #png_dirname = os.path.join(dirname, 'png') #if not os.path.exists(png_dirname): # os.makedirs(png_dirname) if defs.ONLY_FILES_CONTAINING: search_filename = '%s*%s*wav' % ( basename, defs.ONLY_FILES_CONTAINING) else: search_filename = basename + '*.wav' filenames = glob.glob( os.path.join(dirname, search_filename)) filenames = filter(lambda x: "noise" not in x, filenames) filenames.sort() if defs.ONLY_N_FILES > 0: filenames = filenames[:defs.ONLY_N_FILES] _, _, _, final = estimate_f0_B.estimate_f0_B(filenames) f0 = final.f0 B = final.B limit = final.highest_mode stats = HarmonicsStats() stats.num_files = len(filenames) decays = [] for wav_filename_count, wav_filename in enumerate(filenames): basename = os.path.basename(wav_filename) #print "Processing", wav_filename pickle_filename = wav_filename+".stft.pickle" if os.path.exists(pickle_filename): pickle_file = open(pickle_filename, 'rb') harmonics, hop_rate = pickle.load(pickle_file) pickle_file.close() #print "... read pickle" else: #print "... calculating new" #frequency = expected_frequencies.get_freq_from_filename( # wav_filename, f0, B) harmonics, hop_rate = stft_interface.get_harmonics( wav_filename, f0, B, limit) pickle_file = open(pickle_filename, 'wb') pickle.dump( (harmonics, hop_rate), pickle_file, -1) pickle_file.close() #print "... wrote pickle" nums = tables.save_partials(os.path.splitext(basename)[0]) if nums: dest_dir = "out/" for num in nums: h = harmonics[num] #print h.n data = numpy.vstack( ( h.frame_numbers*hop_rate, stft.amplitude2db(h.mags) )).transpose() filename = dest_dir + '/partials-%s-%i.txt' % ( basename, num) numpy.savetxt( filename, data) print "Wrote to %s" % filename for i, h in enumerate(harmonics): stats.num_harms_original += 1 if len(h.mags) < 2: stats.num_harms_max_no_above_noise += 1 continue #if h.n > 0: # pylab.figure() # pylab.semilogy(h.mags, '.') # pylab.title("mode %i" % h.n) # pylab.show() #N = 16 #b, a = scipy.signal.butter(N, 0.25) #b = scipy.signal.firwin(N, 0.25) #a = 1.0 #zi = scipy.signal.lfiltic(b, a, h.mags[0:N], # h.mags[0:N]) #h.mags, zf = scipy.signal.lfilter(b, a, h.mags, # zi=zi) #pylab.semilogy(h.mags) #pylab.show() #if defs.HARMONICS_PRINT_SUMMARY: # print "n: %i\tbegin" %(h.n) noise_mean = get_noise_mean(h.mags, 0.9) #noise_top = get_noise_top(h.mags, 0.9) #frames_above = num_above_noise(h.mags, noise_top) frames_above = num_above_noise(h.mags, noise_mean) #print h.n, "above:", frames_above noise_top_extra_min = stft.db2amplitude( stft.amplitude2db(noise_mean) + defs.HARMONIC_MAX_DB_ABOVE_NOISE_TOP) if max(h.mags) < noise_top_extra_min: # print "bail noise_top_extra" # # FIXME: special stats.num_harms_max_no_above_noise += 1 continue #print h.n, frames_above if frames_above < defs.HARMONIC_MIN_HOPS_ABOVE_NOISE: stats.num_harms_num_no_above_noise += 1 #print "not enough above noise top", frames_above continue ### experiment: only take beginning #h.frame_numbers = h.frame_numbers[:frames_above] #h.mags = h.mags[:frames_above] ### experiment: test the derivative #dh_mags = numpy.zeros(len(h.mags)-1) #for i in range(0, len(h.mags)-1): # subtraction on log scale #dh_mags[i] = (h.mags[i+1] / h.mags[i]) * ( # 1.0 + h.mags[i]) # dh_mags[i] = (h.mags[i+1] - h.mags[i]) #ddh_mags = numpy.zeros(len(dh_mags)) #for i in range(0, len(dh_mags)-1): # ddh_mags[i] = dh_mags[i+1] - dh_mags[i] #dh_mags = (h.mags[1:] - h.mags[:-1]) #sub = (dh_mags > 0) ##print dh_mags * sub #num_below_zero = (dh_mags * sub).sum() #print "bad: %.3g" % (float(num_below_zero) / len(dh_mags) ) ##pylab.plot(dh_mags) ##pylab.show() #print "%.3g\t%.3g\t%.3g\t%.3g" % ( # scipy.std(dh_mags), scipy.median(dh_mags), # scipy.std(ddh_mags), scipy.median(ddh_mags)) #if h.n in defs.HARMONICS_FIT_PLOT_N: #if False: # #pylab.plot(h.mags, '-o') # pylab.plot(dh_mags, '-') # pylab.plot(ddh_mags, '-*') # #pylab.xlim([0, 30]) # # pylab.show() #exit(1) #num_harms_above_noise += 1 ts = hop_rate * h.frame_numbers if h.n == defs.HARMONICS_FIT_PLOT_N: show=True plot=False plot_last=True else: show=False plot=False plot_last=defs.HARMONICS_FIT_PLOT fit, rsquared, variance = decay_exponential.fit_best_exponential( ts, h.mags, noise_mean=noise_mean, show=show, plot=plot, plot_last=plot_last) if fit is None: stats.num_harms_no_fit += 1 print "bail from no fit" continue #alpha = fit[2] alpha = fit[1] #drop_amplitude = fit[0] / noise_mean drop_amplitude = max(h.mags) / noise_mean drop_db = stft.amplitude2db(drop_amplitude) #print drop_db #if drop_db < defs.HARMONIC_MIN_DROP_DB: # stats.num_harms_no_drop += 1 # continue if rsquared < defs.HARMONIC_FIT_MIN_RSQUARED: stats.num_harms_no_rsquared += 1 continue #if variance > defs.HARMONIC_FIT_MAX_VARIANCE: # stats.num_harms_no_variance += 1 # continue #if variance > 1.0: # continue freq = partials.mode_B2freq(f0, h.n, B) w = 2*numpy.pi*freq Q = w / (2*alpha) decay = classes.Decay(freq, w, h.n, alpha, Q, rsquared, variance, drop_db) decays.append(decay) stats.num_harms_end += 1 if defs.HARMONICS_PRINT_SUMMARY: print "n: %i\t%.1f\tdecay: %.2f\tr-squared: %.2f\tvariance: %.2f\tdrop: %.2f db" % ( h.n, freq, alpha, rsquared, variance, drop_db) #print "%s\t%i\t%i\t%i\t%i\t%i" % ( #print "%s\t%i | \t%i\t%i\t%i\t| %i" % ( # basename, # num_harms_original, # num_harms_no_above_noise, # num_harms_no_fit, # #num_harms_no_rsquared, # num_harms_no_drop, # num_harms_end, # ) print "dropped:", stats.num_harms_max_no_above_noise, stats.num_harms_num_no_above_noise, def dot_color(d): #rs = 1.0/d.variance #if rs > 10.: # rs = 10. #rs = 10*d.rsquared rs = d.drop/10.0 rss = rs/10.0 dot = '.' markersize = 5 + 5.0*(rss) color = matplotlib.cm.winter(1.-rss) return dot, color, markersize if defs.HARMONICS_PLOT_DECAYS or plot_harms: pylab.figure() for d in decays: #dot, color, markersize = dot_color(d.rsquared) dot, color, markersize = dot_color(d) pylab.plot(d.n, d.alpha, dot, color=color, markersize=markersize, linewidth=0, ) pylab.xlabel("mode") pylab.ylabel("decay rates") pylab.xlim([0, max([d.n for d in decays])+1]) #pylab.legend() if defs.HARMONICS_PLOT_Q: pylab.figure() #print "# n, loss factor, weight" for d in decays: #print "%i, %.2e, %.2e" %(d.n, 1./d.Q, d.rsquared) #dot, color, markersize = dot_color(1.0/d.variance) dot, color, markersize = dot_color(d) #if d.variance > 10 or d.rsquared < 0.25: #if d.rsquared < 0.3: # dot = 'x' # color = 'red' #else: # print d.variance pylab.plot(d.n, d.Q, dot, color=color, markersize=markersize, linewidth=0, ) pylab.xlabel("mode") pylab.ylabel("Q") pylab.xlim([0, max([d.n for d in decays])+1]) #pylab.legend() if defs.HARMONICS_PLOT_LOSS: pylab.figure() #print "# n, loss factor, weight" for d in decays: #print "%i, %.2e, %.2e" %(d.n, 1./d.Q, d.rsquared) #dot, color, markersize = dot_color(1.0/d.variance) dot, color, markersize = dot_color(d) #if d.variance > 10 or d.rsquared < 0.25: #if d.rsquared < 0.3: # dot = 'x' # color = 'red' #else: # print d.variance pylab.plot(d.n, 1.0/d.Q, dot, color=color, markersize=markersize, linewidth=0, ) pylab.xlabel("mode") pylab.ylabel("loss") pylab.xlim([0, max([d.n for d in decays])+1]) #pylab.legend() ns = [ h.n for h in decays ] stats.highest_harm = max(ns) if (defs.HARMONICS_PLOT_DECAYS or defs.HARMONICS_PLOT_Q or defs.HARMONICS_PLOT_LOSS or plot_harms): pylab.show() return decays, f0, B, stats