X-Git-Url: https://git.sesse.net/?p=pitch;a=blobdiff_plain;f=pitch.cpp;h=36be752bbd66e87163e71921348a95644ebf8b6b;hp=4e0e3eba09fda41c971c9289ebb831662a6faa58;hb=cbf0d7c43e3aa06886d425c4d26c99592eb35ba6;hpb=ed42daa790cfe2942c8c83a729bbce3744bae89b diff --git a/pitch.cpp b/pitch.cpp index 4e0e3eb..36be752 100644 --- a/pitch.cpp +++ b/pitch.cpp @@ -46,7 +46,7 @@ int main() in = reinterpret_cast (fftw_malloc(sizeof(double) * FFT_LENGTH / PAD_FACTOR)); in_windowed = reinterpret_cast (fftw_malloc(sizeof(double) * FFT_LENGTH)); out = reinterpret_cast *> (fftw_malloc(sizeof(std::complex) * (FFT_LENGTH / 2 + 1))); - bins = reinterpret_cast (fftw_malloc(sizeof(double) * FFT_LENGTH / 2 + 1)); + bins = reinterpret_cast (fftw_malloc(sizeof(double) * (FFT_LENGTH / 2 + 1))); memset(in, 0, sizeof(double) * FFT_LENGTH / PAD_FACTOR); @@ -60,7 +60,8 @@ int main() fftw_execute(p); find_peak_magnitudes(out, bins, FFT_LENGTH); std::pair peak = find_peak(bins, FFT_LENGTH); - peak = adjust_for_overtones(peak, bins, FFT_LENGTH); + if (peak.first > 0.0) + peak = adjust_for_overtones(peak, bins, FFT_LENGTH); if (peak.first < 50.0 || peak.second - log10(FFT_LENGTH) < 0.0) { #if TUNING == WELL_TEMPERED_GUITAR @@ -93,7 +94,9 @@ int get_dsp_fd() int rate = SAMPLE_RATE; ioctl(fd, SOUND_PCM_WRITE_RATE, &rate); - int fragments = 0x00020002; + int max_fragments = 2; + int frag_shift = ffs(FFT_LENGTH / OVERLAP) - 1; + int fragments = (max_fragments << 16) | frag_shift; ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragments); ioctl(3, SNDCTL_DSP_SYNC, 0); @@ -187,10 +190,10 @@ void find_peak_magnitudes(std::complex *in, double *out, unsigned num_sa std::pair find_peak(double *in, unsigned num_samples) { - double best_peak = in[0]; - unsigned best_bin = 0; + double best_peak = in[5]; + unsigned best_bin = 5; - for (unsigned i = 1; i < num_samples / 2 + 1; ++i) { + for (unsigned i = 6; i < num_samples / 2 + 1; ++i) { if (in[i] > best_peak) { best_peak = in[i]; best_bin = i; @@ -222,9 +225,9 @@ std::pair find_peak(double *in, unsigned num_samples) best_bin /= i; // consider sliding one bin up or down - if (best_bin > 0 && in[best_bin - 1] > in[best_bin] && in[best_bin - 1] > in[best_bin - 2]) { + if (best_bin > 1 && in[best_bin - 1] > in[best_bin] && in[best_bin - 1] > in[best_bin - 2]) { --best_bin; - } else if (best_bin < num_samples / 2 && in[best_bin + 1] > in[best_bin] && in[best_bin + 1] > in[best_bin + 2]) { + } else if (best_bin < num_samples / 2 - 1 && in[best_bin + 1] > in[best_bin] && in[best_bin + 1] > in[best_bin + 2]) { ++best_bin; } @@ -232,6 +235,9 @@ std::pair find_peak(double *in, unsigned num_samples) } } + if (best_bin == 0 || best_bin == num_samples / 2) { + return std::make_pair(-1.0, 0.0); + } std::pair peak = interpolate_peak(in[best_bin - 1], in[best_bin], @@ -246,12 +252,15 @@ std::pair find_peak(double *in, unsigned num_samples) std::pair adjust_for_overtones(std::pair base, double *in, unsigned num_samples) { double mu = base.first, var = 1.0 / (base.second * base.second); - printf("mu=%f, var=%f\n", mu, var); + + //printf("Base at %.2f (amp=%5.2fdB)\n", base.first, base.second); for (unsigned i = 2; i < 10; ++i) { unsigned middle = unsigned(floor(freq_to_bin(base.first, num_samples) * i + 0.5)); unsigned lower = middle - (i+1)/2, upper = middle + (i+1)/2; + if (lower < 1) + lower = 1; if (upper >= num_samples) upper = num_samples - 2; @@ -286,8 +295,6 @@ std::pair adjust_for_overtones(std::pair base, d double k = var / (var + this_var); mu = (1.0 - k) * mu + k * this_mu; var *= (1.0 - k); - - printf("mu=%f, var=%f\n", mu, var); } return std::make_pair(mu, base.second); }