def plot_B_fit(ns, ys, omit_ns, omit_ys, bin_f0, B, sample_rate, idealss): x = numpy.arange(1, max(ns)+1) predicted = partials.mode_B2freq(bin_f0, x, B) / x ideal_below = partials.mode_B2freq(bin_f0, x, 0) / x ideal_above = ((partials.mode_B2freq(bin_f0, x+1, 0) ) / x / bin_f0) below_bins = int(stft.hertz2bin(bin_f0*defs.B_PEAK_SPREAD_BELOW_HERTZ, sample_rate)) above_bins = int(stft.hertz2bin(bin_f0*defs.B_PEAK_SPREAD_ABOVE_HERTZ, sample_rate)) ideal_above_safe = ((partials.mode_B2freq(bin_f0, x+1, 0) - below_bins - above_bins ) / x / bin_f0) ideal_above_semi_stiff = ((partials.mode_B2freq(bin_f0, x+1, B/4.0) ) / x / bin_f0) ideal_above_above = ((partials.mode_B2freq(bin_f0, x+2, 0) - above_bins ) / x / bin_f0) ideal_ns = numpy.array([ h.n for h in idealss ]) ideal_ys = [ h.fft_bin / h.n for h in idealss ] ideal_ns_next = ideal_ns-1 ideal_ys_next = [ h.fft_bin / (h.n-1) for h in idealss ] ysa = numpy.array(ys) pylab.figure() pylab.plot(ns, ysa, '.') numpy.savetxt("ns_ys.txt", numpy.vstack(( numpy.array(ns), stft.bin2hertz(numpy.array(ysa), sample_rate) )).transpose()) pylab.plot(ideal_ns, ideal_ys, '.', color="green") pylab.plot(ideal_ns_next, ideal_ys_next, '.', color="green") pylab.plot(x, predicted, '-') numpy.savetxt("ns_predicted.txt", numpy.vstack(( numpy.array(x), stft.bin2hertz(numpy.array(predicted), sample_rate) )).transpose()) pylab.plot(x, ideal_below, '-', color="orange") pylab.plot(x, ideal_above_safe, '-', color="pink") pylab.plot(x, ideal_above, '-', color="orange") #pylab.plot(x, ideal_above_above, '-', color="orange") #pylab.plot(x, ideal_above_semi_stiff, '-', color="orange") pylab.plot( omit_ns, omit_ys, 'rx') numpy.savetxt("omit_ns_ys.txt", numpy.vstack(( numpy.array(omit_ns), stft.bin2hertz(numpy.array(omit_ys), sample_rate) )).transpose()) #pylab.plot(xs, weights, 'o') pylab.xlim(0) pylab.ylim([0.99*min(ys), 1.01*max(ys)])
def plot_B_fit(ns, ys, omit_ns, omit_ys, bin_f0, B, sample_rate, idealss): x = numpy.arange(1, max(ns) + 1) predicted = partials.mode_B2freq(bin_f0, x, B) / x ideal_below = partials.mode_B2freq(bin_f0, x, 0) / x ideal_above = ((partials.mode_B2freq(bin_f0, x + 1, 0)) / x / bin_f0) below_bins = int( stft.hertz2bin(bin_f0 * defs.B_PEAK_SPREAD_BELOW_HERTZ, sample_rate)) above_bins = int( stft.hertz2bin(bin_f0 * defs.B_PEAK_SPREAD_ABOVE_HERTZ, sample_rate)) ideal_above_safe = ( (partials.mode_B2freq(bin_f0, x + 1, 0) - below_bins - above_bins) / x / bin_f0) ideal_above_semi_stiff = ((partials.mode_B2freq(bin_f0, x + 1, B / 4.0)) / x / bin_f0) ideal_above_above = ( (partials.mode_B2freq(bin_f0, x + 2, 0) - above_bins) / x / bin_f0) ideal_ns = numpy.array([h.n for h in idealss]) ideal_ys = [h.fft_bin / h.n for h in idealss] ideal_ns_next = ideal_ns - 1 ideal_ys_next = [h.fft_bin / (h.n - 1) for h in idealss] ysa = numpy.array(ys) pylab.figure() pylab.plot(ns, ysa, '.') numpy.savetxt( "ns_ys.txt", numpy.vstack( (numpy.array(ns), stft.bin2hertz(numpy.array(ysa), sample_rate))).transpose()) pylab.plot(ideal_ns, ideal_ys, '.', color="green") pylab.plot(ideal_ns_next, ideal_ys_next, '.', color="green") pylab.plot(x, predicted, '-') numpy.savetxt( "ns_predicted.txt", numpy.vstack( (numpy.array(x), stft.bin2hertz(numpy.array(predicted), sample_rate))).transpose()) pylab.plot(x, ideal_below, '-', color="orange") pylab.plot(x, ideal_above_safe, '-', color="pink") pylab.plot(x, ideal_above, '-', color="orange") #pylab.plot(x, ideal_above_above, '-', color="orange") #pylab.plot(x, ideal_above_semi_stiff, '-', color="orange") pylab.plot(omit_ns, omit_ys, 'rx') numpy.savetxt( "omit_ns_ys.txt", numpy.vstack((numpy.array(omit_ns), stft.bin2hertz(numpy.array(omit_ys), sample_rate))).transpose()) #pylab.plot(xs, weights, 'o') pylab.xlim(0) pylab.ylim([0.99 * min(ys), 1.01 * max(ys)])
def plot_stiff_area(bin_f0, B, bin_spread_below, bin_spread_above, stiff_partials, sample_rate): stiff_bins = numpy.array( [ partials.mode_B2freq( bin_f0, i+1, B) for i in xrange(len(stiff_partials)) ] ) for i, est in enumerate(stiff_bins): low = stft.bin2hertz(est - bin_spread_below, sample_rate) high = stft.bin2hertz(est + bin_spread_above, sample_rate) if i == 0: pylab.axvspan(low, high, color='c', alpha=0.3, label="stiff") else: pylab.axvspan(low, high, color='c', alpha=0.3)
def plot_stiff_area(bin_f0, B, bin_spread_below, bin_spread_above, stiff_partials, sample_rate): stiff_bins = numpy.array([ partials.mode_B2freq(bin_f0, i + 1, B) for i in xrange(len(stiff_partials)) ]) for i, est in enumerate(stiff_bins): low = stft.bin2hertz(est - bin_spread_below, sample_rate) high = stft.bin2hertz(est + bin_spread_above, sample_rate) if i == 0: pylab.axvspan(low, high, color='c', alpha=0.3, label="stiff") else: pylab.axvspan(low, high, color='c', alpha=0.3)
def plot_stft_first_n(window_number, n_windows, fft_amplitude, sample_rate, harms, wav_filename, bin_f0, B, bin_spread_below, bin_spread_above): #if window_number % 2 == 0: count = window_number + 1 color = matplotlib.cm.gnuplot(float(count) / (n_windows + 1)) #label = "%.3f seconds" % (float(count) * stft.HOPSIZE/sample_rate) bin_freqs = [ stft.bin2hertz(bin_num, sample_rate) for bin_num, amplitude in enumerate(fft_amplitude) ] harms_freqs = [ stft.bin2hertz(h.fft_bin, sample_rate) for h in harms if h.mag > 0 ] harms_mags = [stft.amplitude2db(h.mag) for h in harms if h.mag > 0] plot_ideal_lines(bin_f0, len(harms), sample_rate) plot_stiff_area(bin_f0, B, bin_spread_below, bin_spread_above, harms, sample_rate) pylab.plot( bin_freqs, stft.amplitude2db(fft_amplitude), '-', color=color, label="fft", ) pylab.plot( harms_freqs, harms_mags, 'o', color=color, label="harmonics", ) #for est in bins_estimate: # low = stft.bin2hertz(est - bin_spread, sample_rate) # high = stft.bin2hertz(est + bin_spread, sample_rate) # pylab.axvspan(low, high, color='c', alpha=0.3) if window_number >= n_windows - 1: import calc_noise initial_noise_floor, initial_noise_freqs, _, _, _ = calc_noise.get_noise( wav_filename) pylab.plot( initial_noise_freqs, stft.amplitude2db(initial_noise_floor), label="initial noise floor", color="black", )
def plot_resynth(harmonics, fft, sample_rate): freqs = [ stft.bin2hertz(i, sample_rate) for i in xrange(len(fft)) ] synth_min_cutoff = 0.5 * min(numpy.where(fft>0, fft, 1)) length = len(fft) for i, sp in enumerate(harmonics): synthesized_peak = partials.qifft_synthesize(sp.fft_bin, sp.mag, sp.curvature_a, length) synthesized_peak = numpy.where( synthesized_peak > synth_min_cutoff, synthesized_peak, 0) if i == 0: pylab.plot( [ f for f, m in zip(freqs, synthesized_peak) if m > 0.0 ], stft.amplitude2db( numpy.array( [ m for f, m in zip(freqs, synthesized_peak) if m > 0.0 ], )), '.-', color="yellow", alpha=0.8, label="resynthesized peak") else: pylab.plot( [ f for f, m in zip(freqs, synthesized_peak) if m > 0.0 ], stft.amplitude2db( numpy.array( [ m for f, m in zip(freqs, synthesized_peak) if m > 0.0 ], )), '.-', color="yellow", alpha=0.8)
def plot_resynth(harmonics, fft, sample_rate): freqs = [stft.bin2hertz(i, sample_rate) for i in xrange(len(fft))] synth_min_cutoff = 0.5 * min(numpy.where(fft > 0, fft, 1)) length = len(fft) for i, sp in enumerate(harmonics): synthesized_peak = partials.qifft_synthesize(sp.fft_bin, sp.mag, sp.curvature_a, length) synthesized_peak = numpy.where(synthesized_peak > synth_min_cutoff, synthesized_peak, 0) if i == 0: pylab.plot( [f for f, m in zip(freqs, synthesized_peak) if m > 0.0], stft.amplitude2db( numpy.array([ m for f, m in zip(freqs, synthesized_peak) if m > 0.0 ], )), '.-', color="yellow", alpha=0.8, label="resynthesized peak") else: pylab.plot( [f for f, m in zip(freqs, synthesized_peak) if m > 0.0], stft.amplitude2db( numpy.array([ m for f, m in zip(freqs, synthesized_peak) if m > 0.0 ], )), '.-', color="yellow", alpha=0.8)
def plot_peaks(partials, sample_rate): pylab.plot( [ stft.bin2hertz(f.fft_bin, sample_rate) for f in partials], [stft.amplitude2db(f.mag) for f in partials], 'o', color="red", label="detected peaks")
def plot_fft(fft, sample_rate): freqs = [stft.bin2hertz(i, sample_rate) for i in xrange(len(fft))] pylab.plot([f for f, m in zip(freqs, fft) if m > 0.0], [stft.amplitude2db(m) for f, m in zip(freqs, fft) if m > 0.0], '.-', alpha=0.9, label="fft above noise")
def plot_fft(fft, sample_rate): freqs = [ stft.bin2hertz(i, sample_rate) for i in xrange(len(fft)) ] pylab.plot( [ f for f, m in zip(freqs, fft) if m > 0.0 ], [ stft.amplitude2db(m) for f, m in zip(freqs, fft) if m > 0.0 ], '.-', alpha=0.9, label="fft above noise")
def plot_stft_first_n(window_number, n_windows, fft_amplitude, sample_rate, harms, wav_filename, bin_f0, B, bin_spread_below, bin_spread_above ): #if window_number % 2 == 0: count = window_number+1 color = matplotlib.cm.gnuplot(float(count)/(n_windows+1)) #label = "%.3f seconds" % (float(count) * stft.HOPSIZE/sample_rate) bin_freqs = [ stft.bin2hertz(bin_num, sample_rate) for bin_num, amplitude in enumerate(fft_amplitude) ] harms_freqs = [ stft.bin2hertz(h.fft_bin, sample_rate) for h in harms if h.mag > 0] harms_mags = [ stft.amplitude2db(h.mag) for h in harms if h.mag > 0] plot_ideal_lines(bin_f0, len(harms), sample_rate) plot_stiff_area(bin_f0, B, bin_spread_below, bin_spread_above, harms, sample_rate) pylab.plot(bin_freqs, stft.amplitude2db(fft_amplitude), '-', color=color, label="fft", ) pylab.plot(harms_freqs, harms_mags, 'o', color=color, label="harmonics", ) #for est in bins_estimate: # low = stft.bin2hertz(est - bin_spread, sample_rate) # high = stft.bin2hertz(est + bin_spread, sample_rate) # pylab.axvspan(low, high, color='c', alpha=0.3) if window_number >= n_windows - 1: import calc_noise initial_noise_floor, initial_noise_freqs, _, _, _ = calc_noise.get_noise( wav_filename) pylab.plot(initial_noise_freqs, stft.amplitude2db(initial_noise_floor), label="initial noise floor", color="black", )
def plot_ideal_lines(bin_f0, num_harmonics, sample_rate): ideal_freqs = numpy.array( [stft.bin2hertz( partials.mode_B2freq( bin_f0, i+1, 0), sample_rate) for i in xrange(num_harmonics) ] ) for i, line in enumerate(ideal_freqs): if i == 0: pylab.axvline( line, color="pink", #linewidth=3.0, alpha=0.8, label="ideal", ) else: pylab.axvline( line, color="pink", #linewidth=3.0, alpha=0.8, #label="ideal", )
def plot_ideal_lines(bin_f0, num_harmonics, sample_rate): ideal_freqs = numpy.array([ stft.bin2hertz(partials.mode_B2freq(bin_f0, i + 1, 0), sample_rate) for i in xrange(num_harmonics) ]) for i, line in enumerate(ideal_freqs): if i == 0: pylab.axvline( line, color="pink", #linewidth=3.0, alpha=0.8, label="ideal", ) else: pylab.axvline( line, color="pink", #linewidth=3.0, alpha=0.8, #label="ideal", )
def calc_noise(wav_filename, bins=None): window_buffers, sample_rate = stft.get_buffers_from_file(wav_filename) bins = numpy.empty([ stft.WINDOWSIZE / 2 + 1, len(window_buffers), ]) for i, window_buffer in enumerate(window_buffers): fft_amplitude = stft.stft_amplitude(window_buffer) bins[:, i] = fft_amplitude print bins.shape freqs = [ stft.bin2hertz(i, sample_rate) for i in range(stft.WINDOWSIZE / 2 + 1) ] #for i, window_buffer in enumerate(window_buffers): # pylab.plot(freqs, # stft.amplitude2db(bins[:,i]), # color="blue") noise = numpy.empty(len(bins[:, 0])) means = numpy.empty(len(bins[:, 0])) mins = numpy.empty(len(bins[:, 0])) stds = numpy.empty(len(bins[:, 0])) for i, bin_spot in enumerate(bins): detected_noise = scipy.percentile(bin_spot, defs.NOISE_PERCENTILE_BELOW) #noise[i] = stft.db2amplitude(stft.amplitude2db(detected_noise)) noise[i] = detected_noise means[i] = scipy.mean(bin_spot) mins[i] = bin_spot.min() stds[i] = scipy.std(bin_spot, ddof=1) #if i == 100: # numpy.savetxt("noise.csv", bin_spot, delimiter=', ') #return noise, freqs, variance return noise, freqs, means, mins, stds
def calc_noise(wav_filename, bins=None): window_buffers, sample_rate = stft.get_buffers_from_file(wav_filename) bins = numpy.empty([ stft.WINDOWSIZE/2 + 1, len(window_buffers), ]) for i, window_buffer in enumerate(window_buffers): fft_amplitude = stft.stft_amplitude(window_buffer) bins[:,i] = fft_amplitude print bins.shape freqs = [ stft.bin2hertz(i, sample_rate) for i in range(stft.WINDOWSIZE/2 + 1) ] #for i, window_buffer in enumerate(window_buffers): # pylab.plot(freqs, # stft.amplitude2db(bins[:,i]), # color="blue") noise = numpy.empty(len(bins[:,0])) means = numpy.empty(len(bins[:,0])) mins = numpy.empty(len(bins[:,0])) stds = numpy.empty(len(bins[:,0])) for i, bin_spot in enumerate(bins): detected_noise = scipy.percentile(bin_spot, defs.NOISE_PERCENTILE_BELOW) #noise[i] = stft.db2amplitude(stft.amplitude2db(detected_noise)) noise[i] = detected_noise means[i] = scipy.mean(bin_spot) mins[i] = bin_spot.min() stds[i] = scipy.std(bin_spot, ddof=1) #if i == 100: # numpy.savetxt("noise.csv", bin_spot, delimiter=', ') #return noise, freqs, variance return noise, freqs, means, mins, stds
def estimate_f0_B(filenames): ### ASSUME: all filenames are of the same instrument-string wav_filename = filenames[0] basename = '-'.join(os.path.basename(wav_filename).split('-')[0:3]) if basename.startswith("test-440f"): return 440.0, 0, 1, 1, 1, 1 ### get initial f0 estimate base_frequency_estimate = expected_frequencies.get_freq_from_filename( wav_filename) ### get noise initial_noise_floor, initial_noise_freqs, _, _, _ = calc_noise.get_noise( wav_filename) noise_cutoff = stft.db2amplitude( stft.amplitude2db(initial_noise_floor) + defs.B_MINIMUM_HARMONIC_SNR) #### get FFT frames from audio files sample_rate = None freqs = None estimate_B_buffers_list = [] for wav_i, wav_filename in enumerate(filenames): #print wav_filename #window_buffer, sample_rate = stft.get_long_buffer_from_file(wav_filename, window_buffers, sample_rate = stft.get_buffers_from_file( wav_filename, (defs.B_NUM_BUFFERS_ESTIMATE)) if freqs is None: freqs = [ stft.bin2hertz(i, sample_rate) for i in range(stft.WINDOWSIZE / 2 + 1) ] estimate_B_buffers_this_list = [] #fft_amplitude = stft.fft_amplitude(window_buffer, sample_rate) #estimate_B_buffers_this_list.append(fft_amplitude) for window_number in range(defs.B_NUM_BUFFERS_ESTIMATE): window_buffer = window_buffers[window_number] fft_amplitude = stft.stft_amplitude(window_buffer) estimate_B_buffers_this_list.append(fft_amplitude) estimate_B_buffers_list.extend(estimate_B_buffers_this_list) estimate_B_buffers = numpy.array(estimate_B_buffers_list) ### radius of search area for peaks # used with STFT only bin_initial_estimate = stft.hertz2bin(base_frequency_estimate, sample_rate) #bin_initial_estimate = (base_frequency_estimate # * fft_amplitude.shape[0] / (sample_rate/2) # ) #print bin_initial_estimate bin_spread_below = int( math.ceil( abs( stft.hertz2bin((1.0 - defs.B_PEAK_SPREAD_BELOW_HERTZ) * base_frequency_estimate, sample_rate) - bin_initial_estimate))) bin_spread_above = int( math.ceil( stft.hertz2bin((1.0 + defs.B_PEAK_SPREAD_ABOVE_HERTZ) * base_frequency_estimate, sample_rate) - bin_initial_estimate)) #bin_spread_below = int(round(bin_initial_estimate * # defs.B_PEAK_SPREAD_BELOW_HERTZ)) #bin_spread_above = int(round(bin_initial_estimate * # defs.B_PEAK_SPREAD_BELOW_HERTZ)) #bin_spread_below_main = int( # stft.hertz2bin(defs.STFT_PEAK_SPREAD_BELOW_HERTZ*base_frequency_estimate, # sample_rate)) #bin_spread_above_main = int( # stft.hertz2bin(defs.STFT_PEAK_SPREAD_ABOVE_HERTZ*base_frequency_estimate, # sample_rate)) ### actual estimate bin_f0, B, rsquared, harmonics, limit = get_bin_f0_B( bin_initial_estimate, estimate_B_buffers, noise_cutoff, #estimate_B_buffers, numpy.zeros(defs.LONG_WINDOWSIZE+1), bin_spread_below, bin_spread_above, sample_rate) highest_harmonic = 0 for h in harmonics: if highest_harmonic < h.n: highest_harmonic = h.n limit = min(limit, highest_harmonic) # HACK: remove limit #limit = defs.TOTAL_HARMONICS #print "limit to:", limit #harmonics_enable = [True]*defs.TOTAL_HARMONICS harmonics_enable = [True] * limit bins_estimate = [ partials.mode_B2freq(bin_f0, i, B) for i in range(1, len(harmonics_enable) + 1) ] bins_naive = [i * bin_f0 for i in range(1, len(harmonics_enable) + 1)] if defs.B_PLOT: pylab.figure() pylab.plot(initial_noise_freqs, stft.amplitude2db(initial_noise_floor), color='black') #pylab.plot(initial_noise_freqs, # stft.amplitude2db(initial_noise_floor)+defs.B_MINIMUM_HARMONIC_SNR, # color='black') pylab.xlabel("Frequency (seconds)") pylab.ylabel("Power (/ dB)") for i in range(estimate_B_buffers.shape[0]): #color = matplotlib.cm.spring(float(wav_i)/len(filenames)) #color = matplotlib.cm.RdYlGn( #color = matplotlib.cm.spring( # float(i)/len(estimate_B_buffers_this_list)) pylab.plot( freqs, stft.amplitude2db(estimate_B_buffers[i, :]), #color=color, color="orange", alpha=0.5, label=basename, ) for est in bins_estimate: low = stft.bin2hertz(est - bin_spread_below, sample_rate) high = stft.bin2hertz(est + bin_spread_above, sample_rate) if True: pylab.axvspan(low, high, color='c', alpha=0.3) else: pylab.axvline( stft.bin2hertz(est, sample_rate), color='cyan', alpha=0.3, #linewidth=2.0 ) for naive in bins_naive: freq = stft.bin2hertz(naive, sample_rate) pylab.axvline( freq, color='grey', alpha=0.2, #linewidth=2.0 ) for j, harm in enumerate(harmonics): if harm.mag == 0: continue fn = stft.bin2hertz(harm.fft_bin, sample_rate) mag = stft.amplitude2db(harm.mag) #pylab.plot(fn, mag, 'o', # color='green' # ) pylab.xlabel("Frequency") pylab.ylabel("Decibels") if defs.B_DUMP_HARMS: t_fns = [] t_mags = [] for j, harm in enumerate(harmonics): if harm.mag == 0: continue fn = stft.bin2hertz(harm.fft_bin, sample_rate) mag = stft.amplitude2db(harm.mag) t_fns.append(fn) t_mags.append(mag) data = numpy.vstack((t_fns, t_mags)).transpose() numpy.savetxt("B-harms.txt", data) if defs.B_PLOT: pylab.show() f0 = stft.bin2hertz(bin_f0, sample_rate) stiff_ideal_limit = stiff_ideal_conflict.find_limit( bin_f0, B, bin_spread_below, bin_spread_above) lim = min(stiff_ideal_limit, limit) detected_freqs = StringFreqsB(f0, B, lim) stats = StringFreqsB_stats() stats.num_files = len(filenames) stats.rsquared = rsquared stats.highest_mode_detected = limit stats.highest_mode_stiff_ideal = stiff_ideal_limit stats.basename = basename adjusted_B, delta_fn = adjust_B.adjust(basename, limit, f0, B) if adjusted_B is not None: stiff_ideal_lim_adjusted = stiff_ideal_conflict.find_limit( bin_f0, adjusted_B, bin_spread_below, bin_spread_above) lim = min(stiff_ideal_lim_adjusted, limit) adjusted_freqs = StringFreqsB(f0, adjusted_B, lim) adjusted_freqs.delta_fn = delta_fn stats.highest_mode_stiff_ideal_adjusted = stiff_ideal_lim_adjusted stats.delta_fn = delta_fn final = StringFreqsB( f0, adjusted_B, min(stats.highest_mode_detected, stats.highest_mode_stiff_ideal, stiff_ideal_lim_adjusted)) else: adjusted_freqs = None final = StringFreqsB( f0, B, min(stats.highest_mode_detected, stats.highest_mode_stiff_ideal)) return detected_freqs, adjusted_freqs, stats, final
def plot_peaks(partials, sample_rate): pylab.plot([stft.bin2hertz(f.fft_bin, sample_rate) for f in partials], [stft.amplitude2db(f.mag) for f in partials], 'o', color="red", label="detected peaks")
def spectral_subtraction_arrays(data_array, noise_array, sample_rate): #data_array = data_array / float(numpy.iinfo(data_array.dtype).max) #noise_array = data_array / float(numpy.iinfo(noise_array.dtype).max) length = len(data_array) smallsize = int(len(noise_array) / length) noise_data = noise_array[:length*smallsize] noise_data = noise_data.reshape(smallsize, length) #window = scipy.signal.get_window("blackmanharris", length) window = scipy.signal.get_window("hamming", length) noise_data *= window noise_ffts = scipy.fftpack.fft(noise_data, axis=1) noise_ffts_abs = abs(noise_ffts) noise_power = noise_ffts_abs**2 means_power = numpy.mean(noise_power, axis=0) # power to dB noise_db = stft.amplitude2db( numpy.sqrt(means_power[:len(means_power)/2+1])/ length ) freqs = [stft.bin2hertz(i, sample_rate, length) for i in range(len(noise_db))] fft = scipy.fftpack.fft(data_array*window) fft_abs = abs(fft)[:len(fft)/2+1] fft_db = stft.amplitude2db( fft_abs / length ) #reconstructed = fft - mins_full #reconstructed = fft #reconstructed = numpy.zeros(len(fft), dtype=complex) #for i in range(len(reconstructed)): theta = numpy.angle(fft) alpha = 1.0 beta = 0.01 r = numpy.zeros(len(fft)) for i in range(len(fft)): r[i] = (abs(fft[i])**2 - alpha * means_power[i]) if r[i] < beta*means_power[i]: r[i] = beta * means_power[i] # else: # r[i] = numpy.sqrt(r[i]) #print r_orig[i], means_full[i], r[i] r = numpy.sqrt(r) reconstructed = ( r * numpy.cos(theta) + r * numpy.sin(theta)*1j); rec_abs = abs(reconstructed)[:len(reconstructed)/2+1] #print r_abs rec_db = stft.amplitude2db( rec_abs / length ) reconstructed_sig = scipy.fftpack.ifft(reconstructed ) reconstructed_sig /= window reconstructed_sig = numpy.real(reconstructed_sig) median_sig = scipy.signal.medfilt(rec_db, 5) median_sig_orig = scipy.signal.medfilt(fft_db, 5) if False: #if True: #pylab.plot(freqs, noise_db, label="mean noise") pylab.plot(freqs, fft_db, label="sig orig") pylab.plot(freqs, rec_db, label="reconstructed") pylab.plot(freqs, median_sig_orig, label="median orig") pylab.plot(freqs, median_sig, label="median rec.") pylab.legend() pylab.show() return reconstructed_sig
def write_plot(base_filename): filenames = glob.glob(os.path.join( base_filename, "spectrum-*.txt")) basename = base_filename.split('/')[-2] wav_filename = os.path.split( os.path.dirname(base_filename) )[-1] base_freq = expected_frequencies.get_freq_from_filename(wav_filename) filenames.sort() Bs = numpy.loadtxt(os.path.join(base_filename, 'Bs.txt')) SAMPLE_RATE, base_freq, B, limit, below, above = Bs limit = int(limit) num_harms = None for i, filename in enumerate(filenames): seconds = i*HOPSIZE / float(SAMPLE_RATE) if seconds > MAX_SECONDS: print "Reached time cutoff of %.1f" % MAX_SECONDS return print i, filename fft = numpy.loadtxt(filename) harms = numpy.loadtxt(filename.replace("spectrum-", "harms-")) #noise = numpy.loadtxt(os.path.join( # base_filename, "noise-floor.txt")) outfilename = filename.replace("spectrum-","").replace(".txt", ".png") freqs_estimate_int = [ i*base_freq for i in range(1,limit+1)] freqs_estimate_B = [ partials.mode_B2freq(base_freq, i, B) for i in range(1,limit+1)] # DEBUG for g string only for j, freq in enumerate(freqs_estimate_int): if j == 0: pylab.axvline(freq, color="y", label="ideal freq.") else: pylab.axvline(freq, color="y") for j, freq in enumerate(freqs_estimate_B): low = stft.bin2hertz( stft.hertz2bin(freq, SAMPLE_RATE) - below, SAMPLE_RATE) high = stft.bin2hertz( stft.hertz2bin(freq, SAMPLE_RATE) + above, SAMPLE_RATE) if j == 0: pylab.axvspan(low, high, color="c", alpha=0.3, label="search range") else: pylab.axvspan(low, high, color="c", alpha=0.3) pylab.plot(fft[:,0], fft[:,1]) pylab.plot(harms[:,0], harms[:,1], 'ro', label="peaks") #pylab.semilogy(noise[:,0], noise[:,1], 'g-') if num_harms is None: num_harms = len(harms[:,0]) #pylab.xlim([0, (num_harms+3)*base_freq]) if max_freq > 0: pylab.xlim([min_freq, max_freq]) pylab.ylim([AXIS_Y_BOTTOM, AXIS_Y_TOP]) pylab.xlabel("Frequency [Hz]") pylab.ylabel("Amplitude [dB]") pylab.title("Evolution of harmonics: %s\n%.3fs seconds" % ( basename, seconds)) #pylab.legend(bbox_to_anchor=(1.05, 1), loc=2) pylab.legend() pylab.savefig(outfilename) pylab.close()
def calc_harmonics(wav_filename, f0=None, B=None, limit=defs.TOTAL_HARMONICS): if f0 is None: raise Exception("need f0 and B; run another program") # eliminate $HOME ~ and symlinks wav_filename = os.path.realpath(os.path.expanduser(wav_filename)) basename = os.path.splitext(os.path.basename(wav_filename))[0] shared_dirname = os.path.abspath( os.path.join(os.path.dirname(wav_filename), '..')) dest_dir = os.path.join(shared_dirname, "spectrum", basename) if not os.path.exists(dest_dir): os.makedirs(dest_dir) window_buffers, sample_rate = stft.get_buffers_from_file(wav_filename) freqs = [ stft.bin2hertz(i, sample_rate) for i in range(stft.WINDOWSIZE/2+1) ] ### get noise for tuning off low harmonics initial_noise_floor, initial_noise_freqs, _, _, _ = calc_noise.get_noise(wav_filename) noise_cutoff = stft.db2amplitude( stft.amplitude2db(initial_noise_floor) +defs.STFT_MIN_DB_ABOVE_NOISE) bin_f0 = stft.hertz2bin(f0, sample_rate) # radius of search area for peaks bin_spread_below = int( stft.hertz2bin(defs.STFT_PEAK_SPREAD_BELOW_HERTZ*f0, sample_rate)) bin_spread_above = int( stft.hertz2bin(defs.STFT_PEAK_SPREAD_ABOVE_HERTZ*f0, sample_rate)) bin_spread_below = 3 bin_spread_above = 3 if defs.STFT_DUMP_TEXT: write_data.write_Bs(dest_dir, sample_rate, f0, B, limit, bin_spread_below, bin_spread_above) write_data.write_ideals(dest_dir, f0, limit) # store the peaks harmonics = [None]*limit spectrums = [] table_info = tables.save_fft(basename) if table_info: harms_freqs = [] harms_mags = [] if defs.ONLY_N_WINDOWS: window_buffers = window_buffers[:defs.ONLY_N_WINDOWS] for window_number, window_buffer in enumerate(window_buffers): #print '-------- window --- %i' % window_number #fft_amplitude = stft.stft(window_buffer) fft_amplitude = stft.stft_amplitude(window_buffer) if window_number == 0: write_data.write_spectrum(dest_dir, window_number, freqs, stft.amplitude2db(fft_amplitude)) if defs.STFT_DUMP_TEXT: write_data.write_spectrum(dest_dir, window_number, freqs, stft.amplitude2db(fft_amplitude)) spectrums.append(fft_amplitude) # get harmonic peaks, and disable harmonics if can't do harms, _ = partials.get_freqs_mags( limit, bin_f0, B, fft_amplitude, bin_spread_below, bin_spread_above, only_peaks=False) if defs.STFT_PLOT_PARTIALS: plots.plot_partials(fft_amplitude, sample_rate, harms, bin_f0, B, bin_spread_below, bin_spread_above ) if defs.STFT_DUMP_TEXT: dump_freqs = numpy.zeros(limit) dump_mags = numpy.zeros(limit) if table_info: harm_freqs = [] harm_mags = [] for h in harms: i = h.n-1 if harmonics[i] is None: #print stft.bin2hertz(h.fft_bin, sample_rate), h.mag, noise_cutoff[h.fft_bin] harmonics[i] = classes.HarmonicSignal(h.n) #if use_harmonic(h, noise_cutoff, fft_amplitude, # bin_f0, B, # bin_spread_below, bin_spread_above, # ): # harmonics[i] = classes.HarmonicSignal(h.n) #else: # #print "disable harmonic ", n # harmonics[i] = False if harmonics[i] is not False: if h.mag == 0: continue if defs.STFT_DUMP_TEXT: dump_freqs[i] = stft.bin2hertz(h.fft_bin, sample_rate) dump_mags[i] = h.mag if table_info: harm_freqs.append(stft.bin2hertz(h.fft_bin, sample_rate)) harm_mags.append(h.mag) harmonics[i].mags.append(h.mag) harmonics[i].frame_numbers.append(window_number) #print harmonics[i] if table_info: harms_freqs.append(harm_freqs) harms_mags.append(harm_mags) if defs.STFT_DUMP_TEXT: #print dump_mags write_data.write_harms(dest_dir, window_number, dump_freqs, dump_mags, harmonics) if (defs.STFT_PLOT_FIRST_N > 0) and (window_number < defs.STFT_PLOT_FIRST_N): plots.plot_stft_first_n(window_number, defs.STFT_PLOT_FIRST_N, fft_amplitude, sample_rate, harms, wav_filename, bin_f0, B, bin_spread_below, bin_spread_above ) if window_number >= defs.STFT_PLOT_FIRST_N - 1: pylab.show() dh = float(defs.HOPSIZE) / sample_rate if defs.STFT_DUMP_ALL: write_data.write_stft_all(dest_dir, spectrums, freqs, dh) table_info = tables.save_fft(basename) if table_info: for ti in table_info: write_data.write_stft_3d(basename, spectrums, freqs, dh, ti, harms_freqs, harms_mags, sample_rate) # clean up harmonics harmonics = filter(lambda x: x is not False, harmonics) for h in harmonics: h.mags = numpy.array(h.mags) h.frame_numbers = numpy.array(h.frame_numbers) #pylab.plot(stft.amplitude2db(h.mags)) #pylab.show() return harmonics, dh
def write_plot(base_filename): filenames = glob.glob(os.path.join(base_filename, "spectrum-*.txt")) basename = base_filename.split('/')[-2] wav_filename = os.path.split(os.path.dirname(base_filename))[-1] base_freq = expected_frequencies.get_freq_from_filename(wav_filename) filenames.sort() Bs = numpy.loadtxt(os.path.join(base_filename, 'Bs.txt')) SAMPLE_RATE, base_freq, B, limit, below, above = Bs limit = int(limit) num_harms = None for i, filename in enumerate(filenames): seconds = i * HOPSIZE / float(SAMPLE_RATE) if seconds > MAX_SECONDS: print "Reached time cutoff of %.1f" % MAX_SECONDS return print i, filename fft = numpy.loadtxt(filename) harms = numpy.loadtxt(filename.replace("spectrum-", "harms-")) #noise = numpy.loadtxt(os.path.join( # base_filename, "noise-floor.txt")) outfilename = filename.replace("spectrum-", "").replace(".txt", ".png") freqs_estimate_int = [i * base_freq for i in range(1, limit + 1)] freqs_estimate_B = [ partials.mode_B2freq(base_freq, i, B) for i in range(1, limit + 1) ] # DEBUG for g string only for j, freq in enumerate(freqs_estimate_int): if j == 0: pylab.axvline(freq, color="y", label="ideal freq.") else: pylab.axvline(freq, color="y") for j, freq in enumerate(freqs_estimate_B): low = stft.bin2hertz( stft.hertz2bin(freq, SAMPLE_RATE) - below, SAMPLE_RATE) high = stft.bin2hertz( stft.hertz2bin(freq, SAMPLE_RATE) + above, SAMPLE_RATE) if j == 0: pylab.axvspan(low, high, color="c", alpha=0.3, label="search range") else: pylab.axvspan(low, high, color="c", alpha=0.3) pylab.plot(fft[:, 0], fft[:, 1]) pylab.plot(harms[:, 0], harms[:, 1], 'ro', label="peaks") #pylab.semilogy(noise[:,0], noise[:,1], 'g-') if num_harms is None: num_harms = len(harms[:, 0]) #pylab.xlim([0, (num_harms+3)*base_freq]) if max_freq > 0: pylab.xlim([min_freq, max_freq]) pylab.ylim([AXIS_Y_BOTTOM, AXIS_Y_TOP]) pylab.xlabel("Frequency [Hz]") pylab.ylabel("Amplitude [dB]") pylab.title("Evolution of harmonics: %s\n%.3fs seconds" % (basename, seconds)) #pylab.legend(bbox_to_anchor=(1.05, 1), loc=2) pylab.legend() pylab.savefig(outfilename) pylab.close()
def estimate_f0_B(filenames): ### ASSUME: all filenames are of the same instrument-string wav_filename = filenames[0] basename='-'.join(os.path.basename(wav_filename).split('-')[0:3]) if basename.startswith("test-440f"): return 440.0, 0, 1, 1, 1, 1 ### get initial f0 estimate base_frequency_estimate = expected_frequencies.get_freq_from_filename( wav_filename) ### get noise initial_noise_floor, initial_noise_freqs, _, _, _ = calc_noise.get_noise(wav_filename) noise_cutoff = stft.db2amplitude( stft.amplitude2db(initial_noise_floor)+defs.B_MINIMUM_HARMONIC_SNR) #### get FFT frames from audio files sample_rate = None freqs = None estimate_B_buffers_list = [] for wav_i, wav_filename in enumerate(filenames): #print wav_filename #window_buffer, sample_rate = stft.get_long_buffer_from_file(wav_filename, window_buffers, sample_rate = stft.get_buffers_from_file(wav_filename, (defs.B_NUM_BUFFERS_ESTIMATE)) if freqs is None: freqs = [ stft.bin2hertz(i, sample_rate) for i in range(stft.WINDOWSIZE/2+1) ] estimate_B_buffers_this_list = [] #fft_amplitude = stft.fft_amplitude(window_buffer, sample_rate) #estimate_B_buffers_this_list.append(fft_amplitude) for window_number in range(defs.B_NUM_BUFFERS_ESTIMATE): window_buffer = window_buffers[window_number] fft_amplitude = stft.stft_amplitude(window_buffer) estimate_B_buffers_this_list.append(fft_amplitude) estimate_B_buffers_list.extend(estimate_B_buffers_this_list) estimate_B_buffers = numpy.array(estimate_B_buffers_list) ### radius of search area for peaks # used with STFT only bin_initial_estimate = stft.hertz2bin(base_frequency_estimate, sample_rate) #bin_initial_estimate = (base_frequency_estimate # * fft_amplitude.shape[0] / (sample_rate/2) # ) #print bin_initial_estimate bin_spread_below = int(math.ceil(abs( stft.hertz2bin( (1.0-defs.B_PEAK_SPREAD_BELOW_HERTZ)*base_frequency_estimate, sample_rate) - bin_initial_estimate))) bin_spread_above = int(math.ceil( stft.hertz2bin( (1.0+defs.B_PEAK_SPREAD_ABOVE_HERTZ)*base_frequency_estimate, sample_rate) - bin_initial_estimate)) #bin_spread_below = int(round(bin_initial_estimate * # defs.B_PEAK_SPREAD_BELOW_HERTZ)) #bin_spread_above = int(round(bin_initial_estimate * # defs.B_PEAK_SPREAD_BELOW_HERTZ)) #bin_spread_below_main = int( # stft.hertz2bin(defs.STFT_PEAK_SPREAD_BELOW_HERTZ*base_frequency_estimate, # sample_rate)) #bin_spread_above_main = int( # stft.hertz2bin(defs.STFT_PEAK_SPREAD_ABOVE_HERTZ*base_frequency_estimate, # sample_rate)) ### actual estimate bin_f0, B, rsquared, harmonics, limit = get_bin_f0_B( bin_initial_estimate, estimate_B_buffers, noise_cutoff, #estimate_B_buffers, numpy.zeros(defs.LONG_WINDOWSIZE+1), bin_spread_below, bin_spread_above, sample_rate) highest_harmonic = 0 for h in harmonics: if highest_harmonic < h.n: highest_harmonic = h.n limit = min(limit, highest_harmonic) # HACK: remove limit #limit = defs.TOTAL_HARMONICS #print "limit to:", limit #harmonics_enable = [True]*defs.TOTAL_HARMONICS harmonics_enable = [True]*limit bins_estimate = [ partials.mode_B2freq(bin_f0, i, B) for i in range(1,len(harmonics_enable)+1) ] bins_naive = [ i*bin_f0 for i in range(1,len(harmonics_enable)+1) ] if defs.B_PLOT: pylab.figure() pylab.plot(initial_noise_freqs, stft.amplitude2db(initial_noise_floor), color='black') #pylab.plot(initial_noise_freqs, # stft.amplitude2db(initial_noise_floor)+defs.B_MINIMUM_HARMONIC_SNR, # color='black') pylab.xlabel("Frequency (seconds)") pylab.ylabel("Power (/ dB)") for i in range(estimate_B_buffers.shape[0]): #color = matplotlib.cm.spring(float(wav_i)/len(filenames)) #color = matplotlib.cm.RdYlGn( #color = matplotlib.cm.spring( # float(i)/len(estimate_B_buffers_this_list)) pylab.plot(freqs, stft.amplitude2db(estimate_B_buffers[i,:]), #color=color, color="orange", alpha=0.5, label=basename, ) for est in bins_estimate: low = stft.bin2hertz(est - bin_spread_below, sample_rate) high = stft.bin2hertz(est + bin_spread_above, sample_rate) if True: pylab.axvspan(low, high, color='c', alpha=0.3) else: pylab.axvline(stft.bin2hertz(est, sample_rate), color='cyan', alpha=0.3, #linewidth=2.0 ) for naive in bins_naive: freq = stft.bin2hertz(naive, sample_rate) pylab.axvline(freq, color='grey', alpha=0.2, #linewidth=2.0 ) for j, harm in enumerate(harmonics): if harm.mag == 0: continue fn = stft.bin2hertz(harm.fft_bin, sample_rate) mag = stft.amplitude2db(harm.mag) #pylab.plot(fn, mag, 'o', # color='green' # ) pylab.xlabel("Frequency") pylab.ylabel("Decibels") if defs.B_DUMP_HARMS: t_fns = [] t_mags = [] for j, harm in enumerate(harmonics): if harm.mag == 0: continue fn = stft.bin2hertz(harm.fft_bin, sample_rate) mag = stft.amplitude2db(harm.mag) t_fns.append(fn) t_mags.append(mag) data = numpy.vstack((t_fns, t_mags)).transpose() numpy.savetxt("B-harms.txt", data) if defs.B_PLOT: pylab.show() f0 = stft.bin2hertz(bin_f0, sample_rate) stiff_ideal_limit = stiff_ideal_conflict.find_limit(bin_f0, B, bin_spread_below, bin_spread_above) lim = min(stiff_ideal_limit, limit) detected_freqs = StringFreqsB(f0, B, lim) stats = StringFreqsB_stats() stats.num_files = len(filenames) stats.rsquared = rsquared stats.highest_mode_detected = limit stats.highest_mode_stiff_ideal = stiff_ideal_limit stats.basename = basename adjusted_B, delta_fn = adjust_B.adjust(basename, limit, f0, B) if adjusted_B is not None: stiff_ideal_lim_adjusted = stiff_ideal_conflict.find_limit( bin_f0, adjusted_B, bin_spread_below, bin_spread_above) lim = min(stiff_ideal_lim_adjusted, limit) adjusted_freqs = StringFreqsB(f0, adjusted_B, lim) adjusted_freqs.delta_fn = delta_fn stats.highest_mode_stiff_ideal_adjusted = stiff_ideal_lim_adjusted stats.delta_fn = delta_fn final = StringFreqsB(f0, adjusted_B, min(stats.highest_mode_detected, stats.highest_mode_stiff_ideal, stiff_ideal_lim_adjusted)) else: adjusted_freqs = None final = StringFreqsB(f0, B, min(stats.highest_mode_detected, stats.highest_mode_stiff_ideal)) return detected_freqs, adjusted_freqs, stats, final