自相关算法在高频下失败

Autocorrelation algorithm fails in high frequencies

我的吉他调音器有问题。我正在使用自相关算法来查找声音频率。它几乎可以工作。问题从超过 300hz 的高频开始。有时候弹E4(329hz)弦时不确定是329hz还是109hz,我想是次谐波问题。现在我问我如何才能消除那些次谐波?有什么技巧吗?

这是我的自相关代码:

for (int i = 0; i < length; i++) {
    double diff = 0;
    for (int j = 0; j < length; j++) {
        diff += Mathf.Abs (buffer [j] - buffer [i + j]);
    }

    double dx = prevDiff - diff;

    if (dx < 0 && prevDx > 0) {

        if (diff < (0.3 * maxDiff)) {

            if (sampleLen == 0) 
            {
                sampleLen = i - 1;
            }
        }
    }

    prevDx = dx;
    prevDiff = diff;
    maxDiff = Mathf.Max ((float)diff, (float)maxDiff);
}

这是关于不变音高的标准八度不确定性问题。如果一个周期与静止信号中的下一个周期紧密匹配,则 N 个周期也将与接下来的 N 个周期紧密匹配,从而导致在频率间距 and/or 倍频程的几个约数处几乎相同的自相关吃下。噪声量的轻微变化会导致一个音高因数比另一个更好或更差,即使人类可能听不到任何音高差异。

要"fix"这个,你必须从许多几乎相同的相关峰中选择一个。您可以通过对具有完全相同的自相关性的一个候选峰进行加权,使其比另一个候选峰更有可能来做到这一点。例如,您可以要求一个较低的自相关峰值候选者至少比任何峰值高 x%,代表比您 select 较低峰值更高的频率倍数,其中 x% 可能由实验确定(例如之前有多少人类盲人测试小组实际上会听到较低的音调)。该值可能因乐器类型或音色以及演奏的八度音程而异。

另一个技巧是观察声音的谐波演化,因为大弦上低音符的泛音衰减可能与高音弦或音符的谐波不同。