Beispiel #1
0
def get_bin_f0_B(bin_initial_estimate, fft_buffers,
        noise_cutoff, bin_spread_below, bin_spread_above, fs):
    ### gradually discover/refine estimates of bin_f0 and B
    bin_f0 = bin_initial_estimate
    B = 0.0
    limit = defs.TOTAL_HARMONICS
    for i in range(defs.B_INITIAL_PARTIALS, defs.TOTAL_HARMONICS):
        #print fft_buffers.shape
        bin_f0, B, rsquared, ok = align_with_B(i, bin_f0, B, fft_buffers,
            noise_cutoff, bin_spread_below, bin_spread_above,
            fs)
        #print B, rsquared
        limit = stiff_ideal_conflict.find_limit(bin_f0, B,
            bin_spread_below, bin_spread_above)
        #print B, rsquared, limit
        if i > limit:
            ok = False
        #print "%i\t%.2f\t%.2e\t\t%i\t%i" % (
        #    i, bin_f0, B, ok, lim)
        if ok is False:
            break

    rows, columns = fft_buffers.shape
    partialss = []
    idealss = []
    for j in range(rows):
        fft = fft_buffers[j]
        harmonics, ideal_harmonics = partials.get_freqs_mags(defs.TOTAL_HARMONICS, bin_f0, B,
            fft, bin_spread_below, bin_spread_above,
            only_peaks=True, Bsearch=True)
        harmonics = [ h for h in harmonics if h.mag > noise_cutoff[h.fft_bin] ]
        ideal_harmonics = [ h for h in ideal_harmonics if h.mag > noise_cutoff[h.fft_bin] ]
        partialss.extend(harmonics)
        idealss.extend(ideal_harmonics)

    if False:
        pylab.figure()
        ns = [ h.n for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO ]
        pylab.plot( ns,
            [ h.fft_bin - partials.mode_B2freq(bin_f0, h.n, B)
            for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO ],
            '.')
        pylab.show()

    if defs.B_PLOT_FIT:
        ns = [ h.n for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO ]
        ys = [ h.fft_bin / h.n for h in partialss if h.n >
            defs.B_MIN_HARMONIC_FIT_TO ]
        omit_ns = [ h.n for h in partialss if h.n <= defs.B_MIN_HARMONIC_FIT_TO ]
        omit_ys = [ h.fft_bin / h.n for h in partialss if h.n <=
            defs.B_MIN_HARMONIC_FIT_TO ]
        plots.plot_B_fit(ns, ys, omit_ns, omit_ys, bin_f0, B, fs, idealss)
        pylab.show()
    return bin_f0, B, rsquared, partialss, limit
Beispiel #2
0
def align_with_B(num_harmonics, bin_f0, B, ffts,
        noise_cutoff,
        bin_spread_below, bin_spread_above, sample_rate):
    rows, columns = ffts.shape
    partialss = []
    idealss = []
    for j in range(rows):
        fft = ffts[j]
        harmonics, ideal_harmonics = partials.get_freqs_mags(num_harmonics, bin_f0, B,
            fft, bin_spread_below, bin_spread_above,
            only_peaks=True, Bsearch=True)
        if harmonics is None:
            return bin_f0, B, None, False
        harmonics = [ h for h in harmonics if h.mag > noise_cutoff[h.fft_bin] ]
        ideal_harmonics = [ h for h in ideal_harmonics if h.mag > noise_cutoff[h.fft_bin] ]
        partialss.extend(harmonics)
        idealss.extend(ideal_harmonics)

    #ns = [ h.n for h in partialss if h.n > 1 ]
    #ys = [ h.fft_bin / h.n for h in partialss if h.n > 1 ]
    ns = [ h.n for h in partialss if h.n >
        defs.B_MIN_HARMONIC_FIT_TO ]
    ys = [ h.fft_bin / h.n for h in partialss if h.n >
        defs.B_MIN_HARMONIC_FIT_TO ]
    bin_f0, B, rsquared = estimate_B(ns, ys,
        initial_bin_f0=bin_f0, initial_B=B)

    if defs.B_PLOT_FIT_INDIVIDUAL:
        omit_ns = [ h.n for h in partialss if h.n <= defs.B_MIN_HARMONIC_FIT_TO ]
        omit_ys = [ h.fft_bin / h.n for h in partialss if h.n <=
            defs.B_MIN_HARMONIC_FIT_TO ]
        plots.plot_B_fit(ns, ys, omit_ns, omit_ys, bin_f0, B,
            sample_rate, idealss)

        pylab.show()
    return bin_f0, B, rsquared, True
Beispiel #3
0
def get_bin_f0_B(bin_initial_estimate, fft_buffers,
        noise_cutoff, bin_spread_below, bin_spread_above, fs):
    ### gradually discover/refine estimates of bin_f0 and B
    bin_f0 = bin_initial_estimate
    B = 1e-4
    limit = defs.TOTAL_HARMONICS
    for i in range(defs.B_INITIAL_PARTIALS, defs.TOTAL_HARMONICS):
        #print fft_buffers.shape
        bin_f0, B, rsquared, ok = align_with_B(i, bin_f0, B, fft_buffers,
            noise_cutoff, bin_spread_below, bin_spread_above,
            fs)
        limit = stiff_ideal_conflict.find_limit(bin_f0, B,
            bin_spread_below, bin_spread_above)
        #print B, rsquared, limit
        if i > limit:
            #print "warning: exceeding lim?", i, limit
            ok = False
        if defs.B_PRINT_INDIVIDUAL_BS:
            print "%i\t%.4f\t%.5e\t\t%i\t%i" % (
                i, bin_f0, B, ok, 0)
        if ok is False:
            limit = i
            break

    rows, columns = fft_buffers.shape
    partialss = []
    idealss = []
    for j in range(rows):
        fft = fft_buffers[j]
        #harmonics, ideal_harmonics = partials.get_freqs_mags(defs.TOTAL_HARMONICS, bin_f0, B,
        harmonics, ideal_harmonics = partials.get_freqs_mags(limit, bin_f0, B,
            fft, bin_spread_below, bin_spread_above,
            only_peaks=True, Bsearch=True)
        harmonics = [ h for h in harmonics if h.mag > noise_cutoff[h.fft_bin] ]
        ideal_harmonics = [ h for h in ideal_harmonics if h.mag > noise_cutoff[h.fft_bin] ]
        partialss.extend(harmonics)
        idealss.extend(ideal_harmonics)

    #if True:
    if False:
        pylab.figure()
        for j in range(rows):
            fft = fft_buffers[j]
            pylab.plot(stft.amplitude2db(fft), color="orange")

        xs = [ h.fft_bin for h in partialss]
        #if h.n > defs.B_MIN_HARMONIC_FIT_TO ]
        ys = [ h.mag for h in partialss]
        #if h.n > defs.B_MIN_HARMONIC_FIT_TO ]
        pylab.plot(xs, stft.amplitude2db(ys), 'p',
            color="blue")
        pylab.plot(stft.amplitude2db(noise_cutoff), color="black")
        #ns = [ h.n for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO ]
        #pylab.plot( ns,
        #    [ h.fft_bin - partials.mode_B2freq(bin_f0, h.n, B)
        #    for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO ],
        #    '.')
        pylab.show()

    if defs.B_PLOT_FIT:
        ns = [ h.n for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO ]
        ys = [ h.fft_bin / h.n for h in partialss if h.n >
            defs.B_MIN_HARMONIC_FIT_TO ]
        omit_ns = [ h.n for h in partialss if h.n <= defs.B_MIN_HARMONIC_FIT_TO ]
        omit_ys = [ h.fft_bin / h.n for h in partialss if h.n <=
            defs.B_MIN_HARMONIC_FIT_TO ]
        plots.plot_B_fit(ns, ys, omit_ns, omit_ys, bin_f0, B, fs, idealss)
        pylab.show()

    return bin_f0, B, rsquared, partialss, limit
Beispiel #4
0
def align_with_B(num_harmonics, bin_f0, B, ffts,
        noise_cutoff,
        bin_spread_below, bin_spread_above, sample_rate):
    rows, columns = ffts.shape
    partialss = []
    idealss = []
    for j in range(rows):
        fft = ffts[j]
        harmonics, ideal_harmonics = partials.get_freqs_mags(num_harmonics, bin_f0, B,
            fft, bin_spread_below, bin_spread_above,
            only_peaks=True, Bsearch=True)
        if harmonics is None:
            return bin_f0, B, None, False

        harmonics = [ h for h in harmonics if h.mag > noise_cutoff[h.fft_bin] ]
        ideal_harmonics = [ h for h in ideal_harmonics if h.mag > noise_cutoff[h.fft_bin] ]
        partialss.extend(harmonics)
        idealss.extend(ideal_harmonics)

    #ns = [ h.n for h in partialss if h.n > 1 ]
    #ys = [ h.fft_bin / h.n for h in partialss if h.n > 1 ]
    ns = [ h.n for h in partialss if h.n >
        defs.B_MIN_HARMONIC_FIT_TO ]
    ys = [ h.fft_bin / h.n for h in partialss if h.n >
        defs.B_MIN_HARMONIC_FIT_TO ]
    ns_orig = list(ns)
    ys_orig = list(ys)
    ns = []
    ys = []
    weights = []
    #for i, h in enumerate(partialss):
    #    if h.n <= defs.B_MIN_HARMONIC_FIT_TO:
    #        continue
        #if stiff_ideal_conflict.does_confict(bin_f0, B,
        #    bin_spread_below, bin_spread_above, h.n):
        #    #print "bail from conflict"
        #    continue
    #    ns.append( h.n )
    #    ys.append( h.fft_bin / h.n)
    #    weights.append( h.mag - noise_cutoff[h.fft_bin] )
    ns = ns_orig
    ys = ys_orig
    bin_f0, B, rsquared = estimate_B(ns, ys,
        weights,
        initial_bin_f0=bin_f0, initial_B=B)

    if defs.B_PLOT_FIT_INDIVIDUAL:
        omit_ns = [ h.n for h in partialss if h.n <= defs.B_MIN_HARMONIC_FIT_TO ]
        omit_ys = [ h.fft_bin / h.n for h in partialss if h.n <=
            defs.B_MIN_HARMONIC_FIT_TO ]
        plots.plot_B_fit(ns, ys, omit_ns, omit_ys, bin_f0, B,
            sample_rate, idealss)

        pylab.show()

    ok = True
    nums_per = []
    #print '----'
    for n in range(1,num_harmonics+1):
        nums = len( [h.n for h in partialss if h.n == n])
        nums_per.append(nums)
        #print nums,
    if nums_per[num_harmonics-1] < 4:
        #ok = False
        #print "bail", num_harmonics
        pass

    return bin_f0, B, rsquared, ok
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
Beispiel #6
0
def get_bin_f0_B(bin_initial_estimate, fft_buffers, noise_cutoff,
                 bin_spread_below, bin_spread_above, fs):
    ### gradually discover/refine estimates of bin_f0 and B
    bin_f0 = bin_initial_estimate
    B = 1e-4
    limit = defs.TOTAL_HARMONICS
    for i in range(defs.B_INITIAL_PARTIALS, defs.TOTAL_HARMONICS):
        #print fft_buffers.shape
        bin_f0, B, rsquared, ok = align_with_B(i, bin_f0, B, fft_buffers,
                                               noise_cutoff, bin_spread_below,
                                               bin_spread_above, fs)
        limit = stiff_ideal_conflict.find_limit(bin_f0, B, bin_spread_below,
                                                bin_spread_above)
        #print B, rsquared, limit
        if i > limit:
            #print "warning: exceeding lim?", i, limit
            ok = False
        if defs.B_PRINT_INDIVIDUAL_BS:
            print "%i\t%.4f\t%.5e\t\t%i\t%i" % (i, bin_f0, B, ok, 0)
        if ok is False:
            limit = i
            break

    rows, columns = fft_buffers.shape
    partialss = []
    idealss = []
    for j in range(rows):
        fft = fft_buffers[j]
        #harmonics, ideal_harmonics = partials.get_freqs_mags(defs.TOTAL_HARMONICS, bin_f0, B,
        harmonics, ideal_harmonics = partials.get_freqs_mags(limit,
                                                             bin_f0,
                                                             B,
                                                             fft,
                                                             bin_spread_below,
                                                             bin_spread_above,
                                                             only_peaks=True,
                                                             Bsearch=True)
        harmonics = [h for h in harmonics if h.mag > noise_cutoff[h.fft_bin]]
        ideal_harmonics = [
            h for h in ideal_harmonics if h.mag > noise_cutoff[h.fft_bin]
        ]
        partialss.extend(harmonics)
        idealss.extend(ideal_harmonics)

    #if True:
    if False:
        pylab.figure()
        for j in range(rows):
            fft = fft_buffers[j]
            pylab.plot(stft.amplitude2db(fft), color="orange")

        xs = [h.fft_bin for h in partialss]
        #if h.n > defs.B_MIN_HARMONIC_FIT_TO ]
        ys = [h.mag for h in partialss]
        #if h.n > defs.B_MIN_HARMONIC_FIT_TO ]
        pylab.plot(xs, stft.amplitude2db(ys), 'p', color="blue")
        pylab.plot(stft.amplitude2db(noise_cutoff), color="black")
        #ns = [ h.n for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO ]
        #pylab.plot( ns,
        #    [ h.fft_bin - partials.mode_B2freq(bin_f0, h.n, B)
        #    for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO ],
        #    '.')
        pylab.show()

    if defs.B_PLOT_FIT:
        ns = [h.n for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO]
        ys = [
            h.fft_bin / h.n for h in partialss
            if h.n > defs.B_MIN_HARMONIC_FIT_TO
        ]
        omit_ns = [h.n for h in partialss if h.n <= defs.B_MIN_HARMONIC_FIT_TO]
        omit_ys = [
            h.fft_bin / h.n for h in partialss
            if h.n <= defs.B_MIN_HARMONIC_FIT_TO
        ]
        plots.plot_B_fit(ns, ys, omit_ns, omit_ys, bin_f0, B, fs, idealss)
        pylab.show()

    return bin_f0, B, rsquared, partialss, limit
Beispiel #7
0
def align_with_B(num_harmonics, bin_f0, B, ffts, noise_cutoff,
                 bin_spread_below, bin_spread_above, sample_rate):
    rows, columns = ffts.shape
    partialss = []
    idealss = []
    for j in range(rows):
        fft = ffts[j]
        harmonics, ideal_harmonics = partials.get_freqs_mags(num_harmonics,
                                                             bin_f0,
                                                             B,
                                                             fft,
                                                             bin_spread_below,
                                                             bin_spread_above,
                                                             only_peaks=True,
                                                             Bsearch=True)
        if harmonics is None:
            return bin_f0, B, None, False

        harmonics = [h for h in harmonics if h.mag > noise_cutoff[h.fft_bin]]
        ideal_harmonics = [
            h for h in ideal_harmonics if h.mag > noise_cutoff[h.fft_bin]
        ]
        partialss.extend(harmonics)
        idealss.extend(ideal_harmonics)

    #ns = [ h.n for h in partialss if h.n > 1 ]
    #ys = [ h.fft_bin / h.n for h in partialss if h.n > 1 ]
    ns = [h.n for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO]
    ys = [
        h.fft_bin / h.n for h in partialss if h.n > defs.B_MIN_HARMONIC_FIT_TO
    ]
    ns_orig = list(ns)
    ys_orig = list(ys)
    ns = []
    ys = []
    weights = []
    #for i, h in enumerate(partialss):
    #    if h.n <= defs.B_MIN_HARMONIC_FIT_TO:
    #        continue
    #if stiff_ideal_conflict.does_confict(bin_f0, B,
    #    bin_spread_below, bin_spread_above, h.n):
    #    #print "bail from conflict"
    #    continue
    #    ns.append( h.n )
    #    ys.append( h.fft_bin / h.n)
    #    weights.append( h.mag - noise_cutoff[h.fft_bin] )
    ns = ns_orig
    ys = ys_orig
    bin_f0, B, rsquared = estimate_B(ns,
                                     ys,
                                     weights,
                                     initial_bin_f0=bin_f0,
                                     initial_B=B)

    if defs.B_PLOT_FIT_INDIVIDUAL:
        omit_ns = [h.n for h in partialss if h.n <= defs.B_MIN_HARMONIC_FIT_TO]
        omit_ys = [
            h.fft_bin / h.n for h in partialss
            if h.n <= defs.B_MIN_HARMONIC_FIT_TO
        ]
        plots.plot_B_fit(ns, ys, omit_ns, omit_ys, bin_f0, B, sample_rate,
                         idealss)

        pylab.show()

    ok = True
    nums_per = []
    #print '----'
    for n in range(1, num_harmonics + 1):
        nums = len([h.n for h in partialss if h.n == n])
        nums_per.append(nums)
        #print nums,
    if nums_per[num_harmonics - 1] < 4:
        #ok = False
        #print "bail", num_harmonics
        pass

    return bin_f0, B, rsquared, ok