コード例 #1
0
ファイル: long-fft.py プロジェクト: nickbailey/artifastring
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
コード例 #2
0
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)
コード例 #3
0
ファイル: spectogram.py プロジェクト: gperciva/artifastring
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
コード例 #4
0
ファイル: cutoff.py プロジェクト: nickbailey/artifastring
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
コード例 #5
0
ファイル: long-fft.py プロジェクト: nickbailey/artifastring
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