我已经使用 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; }