Я реализовал этот алгоритм для Performous сам.Когда вы берете другое БПФ со смещением по времени, вы ожидаете, что фаза изменится в соответствии со смещением, то есть два БПФ, взятые с интервалом 256 выборок, должны иметь разность фаз 256 выборок для всех частот, присутствующих в сигнале (это предполагает, что сами сигналыустойчивы, что является хорошим предположением для коротких периодов, таких как 256 выборок).
Теперь фактические значения фазы, которые вы получаете из БПФ, не в выборках, а в фазовом угле, поэтому они будут отличаться в зависимости от частоты,В следующем коде значение phaseStep - это коэффициент преобразования, необходимый для каждого элемента, т. Е. Для частоты, соответствующей элементу x, сдвиг фазы будет равен x * phaseStep.Для центральных частот ячейки x будет целым числом (номером ячейки), но для фактических обнаруженных частот это может быть любое действительное число.
const double freqPerBin = SAMPLE_RATE / FFT_N;
const double phaseStep = 2.0 * M_PI * FFT_STEP / FFT_N;
Коррекция работает, предполагая, что сигнал в ячейке имеет центр ячейкичастота, а затем рассчитать ожидаемый сдвиг фазы для этого.Этот ожидаемый сдвиг вычитается из фактического сдвига, оставляя ошибку.Остаток (по модулю 2 pi) берется (от -pi до pi-диапазона), и окончательная частота вычисляется с помощью центра + коррекции бина.
// process phase difference
double delta = phase - m_fftLastPhase[k];
m_fftLastPhase[k] = phase;
delta -= k * phaseStep; // subtract expected phase difference
delta = remainder(delta, 2.0 * M_PI); // map delta phase into +/- M_PI interval
delta /= phaseStep; // calculate diff from bin center frequency
double freq = (k + delta) * freqPerBin; // calculate the true frequency
Обратите внимание, что многие смежные бины часто заканчиваются коррекцией на одну и ту же частоту.поскольку дельта-коррекция может составлять до 0,5 * FFT_N / FFT_STEP в любом случае, поэтому чем меньше FFT_STEP, который вы используете, тем дальше будут возможны коррекции (но это увеличивает необходимую вычислительную мощность, а также неточность из-за неточностей).
Надеюсь, это поможет:)