HPSを使用してピッチ検出アルゴリズムを作成しましたが、問題に直面しています。私は信号処理の初心者ですが、このサイトは以前から役に立ちました。
より高いピッチ(eg. >C6:1046.50hz
)については、HPSからガベージデータを取得し始めています。ピッチが高いほど、多くのゴミが発生します(ゴミとは、オクターブエラーや高調波ではなく、約1Hz〜20Hzの周波数を意味します)
私が経験的に観察したこと:
ピッチが高くなると結果は最悪になります。ファンダメンタルズがA6程度以上の場合、ガベージデータのみを取得します。
FFTは、非常に高いピッチでも正常に機能します(細かく言うと、ピークは基本波またはその高調波のいずれかを示しますが、ガベージは示しません)。
HPSで考慮する高調波の数を減らすと、ゴミは減りますが、基本波と高調波を区別するのが難しくなります。
これが私のアルゴリズムです:
->raw buffer -> hann window, 16384 samples, 50% overlap -> zero padding -> FFT -> HPS
どんな助けでもありがたいです!
更新1:では、追加したいことがいくつかあります。
- 私が記録しているサンプルレートは44100 Hzです
- この振る舞いはギターではほとんど見えないが、デジタルピアノでは非常によく見えることを確認しました(同じ演奏ノートに対して)
これが私の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; }