def process(wav_filename, expected_peak_freq): sample_rate, data_unnormalized = scipy.io.wavfile.read(wav_filename) data = (numpy.array(data_unnormalized, dtype=numpy.float64) / float(numpy.iinfo(data_unnormalized.dtype).max)) # expermental: remove some data #data = data[0.2*len(data):0.5*len(data)] if SHORT: data = data[:SHORT] freqs, fft, phase, fft_length = get_freqs_fft(data, sample_rate) fft_db = dsp.amplitude2db(fft) if NORMALIZE_DB: fft_db -= max(fft_db) filename = "%s-freqs.txt" % (os.path.splitext(wav_filename)[0] ) numpy.savetxt( filename, numpy.vstack( (freqs, fft_db)).transpose() ) low_freq = expected_peak_freq - FREQ_WIDTH high_freq = expected_peak_freq + FREQ_WIDTH low_bin = hertz2bin(low_freq, sample_rate, fft_length) high_bin = hertz2bin(high_freq, sample_rate, fft_length) freqs = freqs [low_bin:high_bin] fft_db = fft_db[low_bin:high_bin] phase = phase [low_bin:high_bin] return freqs, fft_db, phase
def process(filename): sample_rate, data_unnormalized = scipy.io.wavfile.read(filename) data = numpy.array(data_unnormalized, dtype=numpy.float64) data = data_unnormalized / float(numpy.iinfo(data_unnormalized.dtype).max) #data = scipy.signal.decimate(data, 2) #sample_rate /= 2.0 cutoff = 20.0 / (sample_rate/2.0) pylab.plot(data) b, a = scipy.signal.butter(4, cutoff, btype='highpass') data = scipy.signal.lfilter(b, a, data) #pylab.plot(data) #pylab.ylim([-1,1]) #pylab.show() #data = numpy.array(data, dtype=numpy.int32) data_abs = abs(data) ind = data_abs.argmax() xs = numpy.arange(0, len(data)) orientation = float(data[ind]) for f in xrange(ind, ind-1000, -1): # is a zero crossing #print orientation, data[f] if orientation * data[f] <= 0: zero = f break #print ind, zero save = data [zero : zero+4096] xs_save = xs[zero : zero+4096] #print filename, ind, zero #pylab.plot(xs[:ind], data[:ind]) #pylab.plot(xs_save[:500], save[:500]) #pylab.show() out_filename = os.path.join(split_dir, os.path.basename(filename)) saveints = numpy.array( save * float((2**16)-1), dtype=numpy.int16) scipy.io.wavfile.write(out_filename, sample_rate, saveints) #fft = scipy.fftpack.fft(save / float(numpy.iinfo(save.dtype).max)) fft = scipy.fftpack.fft(save) fftabs = abs(fft[:len(fft)/2]) / len(save) freqs = numpy.array([ float(i) * sample_rate / len(fft) for i in xrange(len(fftabs)) ]) fftdb = dsp.amplitude2db(fftabs) data = numpy.vstack( (freqs, fftdb) ).transpose() numpy.savetxt(out_filename[:-4] + ".freqs.txt", data) data = numpy.vstack( ( numpy.arange(0, len(save))/44100.0, save * float(2**31-1) ) ).transpose() numpy.savetxt(out_filename[:-4] + ".time.txt", data)
def fit_lorentzian(freqs, fft_db, plot=False, add_plot=False): w = freqs y = dsp.db2amplitude(fft_db) #y = fft_db #w = numpy.array( [ # bin2hertz(bin_low+i) for i, a in enumerate(peak_area) # ] ) #y = numpy.array(peak_area) #noise_floor = scipy.stats.gmean(y) noise_floor = min(y) mag_est = max(y) - noise_floor initial_guess = numpy.array([1.0, w.mean(), mag_est, noise_floor ]) #print "initial:", initial_guess p, pcov = scipy.optimize.curve_fit( lorentzian, w, y, initial_guess, ) #print "fit:", p predicted = lorentzian(w, *p) #if plot: # #pylab.plot(w, dsp.amplitude2db(y), label="FFT") # #pylab.plot(w, dsp.amplitude2db(predicted), # # label="Lorentzian fit") # pylab.plot(w, y, label="FFT") # pylab.plot(w, predicted, # label="Lorentzian fit") # pylab.show() # ss_err = ((y - predicted)**2).sum() ss_tot = ((y-y.mean())**2).sum() rsquared = 1.-(ss_err/ss_tot) #try: # variance = pcov[0][0] #except: # print "bail from variance" # return None, 0, 0, 0 variance = 0 freq = p[1] mag = p[2] decay = 2*numpy.pi / abs(p[0]) #print "Fit first:\t%.1f\t%.2g\t%.3g" % ( print "%.2f\t%.3g\t%.4g" % ( freq, mag, decay) #if rsquared < LONG_LORENTZIAN_RSQUARED_MIN: # print "bail from rsquared", rsquared # return freq, 0, 0, 0 if plot: logplot = True pylab.figure() if logplot: pylab.plot(w, dsp.amplitude2db(y), label="FFT") pylab.plot(w, dsp.amplitude2db(predicted), label="Lorentzian fit") #pylab.semilogy(w, resi, label="residuals") else: pylab.plot(w, y, label="FFT") pylab.plot(w, predicted, label="Lorentzian fit") #pylab.plot(w, resi, label="residuals") #pylab.xlabel("frequency relative to w_n") pylab.xlabel("frequency") pylab.ylabel("power") pylab.legend() pylab.show() if add_plot: low = min(w_eval) high = max(w_eval) pylab.axvspan(low, high, color='c', alpha=0.3, label="stiff") pylab.plot(w_eval, numpy.log(predicted), #pylab.plot(w_eval, (predicted), label="Lorentzian fit", color="red") return freq, decay, rsquared, variance
def pluck_force(violin, st, force, finger, plot=False, write=False): #violin = artifastring_instrument.ArtifastringInstrument(inst, instnum) #wavfile = monowav.MonoWav("artifastring-test.wav") violin.reset() violin.finger(st, finger) violin.pluck(st, 0.2, force) def hop(): buf = numpy.empty(HOPSIZE, dtype=numpy.int16) forces = numpy.empty(FORCE_SIZE, dtype=numpy.int16) violin.wait_samples_forces_python(buf, forces) string_array = numpy.zeros(4*HOPSIZE, dtype=numpy.float32) string_array_size = violin.get_string_buffer(st, string_array) string_array = string_array[:string_array_size] #pylab.plot(string_array) #pylab.show() buf_rms = numpy.sqrt(numpy.mean(numpy.array(buf, numpy.float64)**2)) sa_rms = numpy.sqrt(numpy.mean(numpy.array(string_array, dtype=numpy.float64)**2)) buf_ss = numpy.sum(numpy.array(buf, numpy.float64)**2) sa_ss = numpy.sum(numpy.array(string_array, dtype=numpy.float64)**2) return buf_rms, sa_rms, buf_ss, sa_ss dh = float(HOPSIZE) / artifastring_instrument.ARTIFASTRING_INSTRUMENT_SAMPLE_RATE BUFS = 1000 dhs = numpy.arange(0, BUFS) * dh buf = numpy.zeros(BUFS) sa = numpy.zeros(BUFS) buf_sss = numpy.zeros(BUFS) sa_sss = numpy.zeros(BUFS) for i in range(BUFS): buf_this, string_array_this, buf_ss, sa_ss = hop() buf[i] = buf_this sa[i] = string_array_this buf_sss[i] = buf_ss sa_sss[i] = sa_ss buf_db = dsp.amplitude2db(buf) sa_db = dsp.amplitude2db(sa) cutoff_hop = 0 for i in range(BUFS): if buf_db[i] < CUTOFF_DB_FINAL_AUDIO: cutoff_hop = i break print "cutoff time:", cutoff_hop*dh cutoff_internal_audio = sa_sss[cutoff_hop] cutoff_internal_audio_db = sa_db[cutoff_hop] #print "Cutoff internal audio:", cutoff_internal_audio if write: numpy.savetxt("instrument-%i-%.3f-db.txt" % ( st,finger), numpy.vstack( ( dhs, buf_db )).transpose()) numpy.savetxt("string-%i-%.3f-db.txt" % ( st,finger), numpy.vstack( ( dhs, sa_db )).transpose()) numpy.savetxt("cutoff-%i-%.3f.txt" % ( st,finger), numpy.array([ [0, cutoff_internal_audio_db], [BUFS*dh, cutoff_internal_audio_db] ]) ) if plot: pylab.subplot(211) pylab.title("Final audio") pylab.plot(dhs, buf_db) pylab.axhline(CUTOFF_DB_FINAL_AUDIO) pylab.subplot(212) pylab.title("String audio") pylab.plot(dhs, sa_db, '.-') pylab.axhline(cutoff_internal_audio_db) pylab.show() return cutoff_internal_audio
def fit_area(freqs, fft_db, plot=False, add_plot=False): w = freqs y = dsp.db2amplitude(fft_db) #y = fft_db #w = numpy.array( [ # bin2hertz(bin_low+i) for i, a in enumerate(peak_area) # ] ) #y = numpy.array(peak_area) global noise_floor #noise_floor = scipy.stats.gmean(y) noise_floor = min(y) mag_est = max(y) - noise_floor initial_guess = numpy.array([1.0, w.mean(), mag_est ]) print "initial:", initial_guess p, pcov = scipy.optimize.curve_fit( lorentzian, w, y, initial_guess, ) print "fit:", p freq = p[1] mag = p[2] decay = 2*numpy.pi / abs(p[0]) print "Fit only:\t%.1f\t%.2g\t%.3g" % ( freq, mag, decay) predicted = lorentzian(w, *p) rem = y - predicted #if False: if True: pylab.plot(w, dsp.amplitude2db(y), label="FFT") pylab.plot(w, dsp.amplitude2db(predicted), label="Lorentzian fit") pylab.plot(w, dsp.amplitude2db(rem), label="residual") #pylab.plot(w, y, label="FFT") #pylab.plot(w, predicted, # label="Lorentzian fit") pylab.show() #double_guess = numpy.array([ p[0], p[1], p[2], p[0], p[1], # p[2]/100.0]) double_guess = numpy.array([ p[0], p[1], p[2], 1.2, 96.3, 200.0]) #print "double guess:" #print double_guess p, pcov = scipy.optimize.curve_fit( lorentzian_two, w, y, double_guess ) print "fit two:" print p predicted = lorentzian_two(w, *p) #logplot = False #pylab.figure() #if logplot: # pylab.semilogy(w, y, '.', label="FFT") # pylab.semilogy(w_eval, predicted, label="Lorentzian fit") # pylab.show() #else: # pylab.plot(w, y, '.', label="FFT") # pylab.plot(w_eval, predicted, label="Lorentzian fit") # pylab.show() ss_err = ((y - predicted)**2).sum() ss_tot = ((y-y.mean())**2).sum() rsquared = 1.-(ss_err/ss_tot) #try: # variance = pcov[0][0] #except: # print "bail from variance" # return None, 0, 0, 0 variance = 0 freq = p[1] mag = p[2] decay = 2*numpy.pi / abs(p[0]) print "Fit first:\t%.1f\t%.2g\t%.3g" % ( freq, mag, decay) print "Fit second :\t%.1f\t%.2g\t%.3g" % ( p[4], p[5], 2*numpy.pi / abs(p[3])) #if rsquared < LONG_LORENTZIAN_RSQUARED_MIN: # print "bail from rsquared", rsquared # return freq, 0, 0, 0 rem = y - predicted if plot: logplot = True pylab.figure() if logplot: pylab.plot(w, dsp.amplitude2db(y), label="FFT") pylab.plot(w, dsp.amplitude2db(predicted), label="Lorentzian fit") pylab.plot(w, dsp.amplitude2db(rem), label="residual") #pylab.semilogy(w, resi, label="residuals") else: pylab.plot(w, y, label="FFT") pylab.plot(w, predicted, label="Lorentzian fit") #pylab.plot(w, resi, label="residuals") #pylab.xlabel("frequency relative to w_n") pylab.xlabel("frequency") pylab.ylabel("power") pylab.legend() if add_plot: low = min(w_eval) high = max(w_eval) pylab.axvspan(low, high, color='c', alpha=0.3, label="stiff") pylab.plot(w_eval, numpy.log(predicted), #pylab.plot(w_eval, (predicted), label="Lorentzian fit", color="red") return freq, decay, rsquared, variance