音高检测中的谐波产物频谱限制

信息处理 傅里叶变换 频谱 沥青
2022-01-17 13:22:47

我已经使用 HPS 制作了一个音高检测算法,但我遇到了一个问题。我是信号处理的初学者,这个网站以前帮助过我,所以我应该问一下。

对于更高的音高 ( eg. >C6:1046.50hz),我开始从 HPS 获取垃圾数据。音高越高,我得到的垃圾就越多(垃圾是指不是八度音阶误差也不是谐波并且在 1Hz-20Hz 左右的频率)

我的经验观察:

  1. 对于更高的音高,结果最差,如果基本高于 A6 左右,我只会得到垃圾数据。

  2. 即使对于非常高的音高,FFT 也能正常工作,(我的意思是它的峰值显示基波或其谐波之一,但不是垃圾)

  3. 如果我降低考虑到 HPS 的谐波数量,垃圾就会减少,但这使得区分基波和谐波变得更加困难。

这是我的算法:

->raw buffer -> hann window, 16384 samples, 50% overlap -> zero padding -> FFT -> HPS

任何帮助表示赞赏!

更新 1:所以,我还想补充几点:

  1. 我录制的采样率为 44100 Hz
  2. 我观察到这种行为在吉他上几乎看不到,但在数码钢琴上却非常明显(对于相同的演奏音符)
  3. 这是我的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;
    }
    
2个回答

可能是在这些较高音高的信号中存在太少的谐波部分。HPS 算法非常简单,依靠这些高次谐波不断叠加,直到基波从背景中出现。当然,我们应该想知道,您的采样率是多少?如果它是 8000 赫兹,那么 1000 赫兹音高的 3 个谐波只有空间......

对于某些乐器,产生的重要谐波的数量可能会在不同的音高范围内发生变化。某些物理乐器的最低和最高音符的部分可能表现出更大的不和谐。对于非常高的音符,可以适合低于 Fs/2 的抗混叠滤波器截止频率的谐波数量肯定会更低。您的 HPS 音高估算器 mdy 希望将这些因素考虑在内。

某些乐器的起音瞬态可能会产生非谐波频谱带,它可能与某些音高的 HPS 搜索区域或其重要谐波重叠。

如果音频 ADC 之前的低通滤波器没有足够好的阻带衰减,那么非常高频率的泛音甚至可能环绕 Fs/2。