Я сделал алгоритм определения высоты тона, используя HPS, и я столкнулся с проблемой. Я новичок в обработке сигналов, и этот сайт помог мне раньше, поэтому я должен спросить.
Для более высоких частот ( eg. >C6:1046.50hz
) я начинаю получать данные мусора от HPS. Чем выше высота, тем больше мусора я получаю (под мусором я подразумеваю частоты, которые не являются ошибками октавы или гармониками и составляют около 1 Гц-20 Гц)
Что я наблюдал эмпирически:
результаты наихудшие для более высоких частот, если основной выше A6 или около того, я получаю только данные мусора.
БПФ отлично работает даже для очень высокого шага (под тонкой я имею в виду, что его пик показывает либо фундаментальную, либо одну из его гармоник, но не мусор)
если я уменьшу количество гармоник, которые я принимаю во внимание для HPS, мусор уменьшится, но это затруднит различие между основной и гармоникой.
Вот мой алгоритм:
->raw buffer -> hann window, 16384 samples, 50% overlap -> zero padding -> FFT -> HPS
Любая помощь приветствуется!
ОБНОВЛЕНИЕ 1: Итак, я хочу добавить еще несколько вещей:
- Частота дискретизации, на которой я записываю, составляет 44100 Гц
- Я заметил, что это поведение едва заметно на гитаре, но очень заметно на цифровом пианино (для той же самой сыгранной ноты)
Вот мой алгоритм hps, может быть, кто-то с большим опытом может обнаружить проблему.
int hps(float* spectrum, int spectrumSize, int harmonics) { int i, j, maxSearchIndex, maxBin; maxSearchIndex = spectrumSize/harmonics; maxBin = 1; for (j=1; j<=maxSearchIndex; j++) { for (i=1; i<=harmonics; i++) { spectrum[j] *= spectrum[j*i]; } if (spectrum[j] > spectrum[maxBin]) { maxBin = j; } } // Fixing octave too high errors int correctMaxBin = 1; int maxsearch = maxBin * 3 / 4; for (i=2; i<maxsearch; i++) { if (spectrum[i] > spectrum[correctMaxBin]) { correctMaxBin = i; } } if (abs(correctMaxBin * 2 - maxBin) < 4) { if (spectrum[correctMaxBin]/spectrum[maxBin] > 0.2) { maxBin = correctMaxBin; } } return maxBin; }