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