我正在创建一个语音训练应用程序,并使用 FFT 将信号从时域转换为频域。在应用 FFT 之前,我已经使用 blackman-harris 窗口对信号进行了窗口化。然后我使用谐波产品频谱来提取基频。最低频率为 F2 (87.307 Hz),最高频率为 C6 (1046.502 Hz)。FFT 长度为 8192,采样频率为 44100 Hz。
为了修复八度音阶错误,我应用了这里提到的规则;
float[] array = hps.HPS(Data);
float hpsmax_mag = float.MinValue;
float hpsmax_index = -1;
for (int i = 0; i < array.Length; i++)
if (array[i] > hpsmax_mag)
{
hpsmax_mag = array[i];
hpsmax_index = i;
}
// Fixing octave too high errors
int correctMaxBin = 1;
int maxsearch = (int) hpsmax_index * 3 / 4;
for (int j = 2; j < maxsearch; j++)
{
if (array[j] > array[correctMaxBin])
{
correctMaxBin = j;
}
}
if (Math.Abs(correctMaxBin * 2 - hpsmax_index) < 4)
{
if (array[correctMaxBin] / array[(int)hpsmax_index] > 0.2)
{
hpsmax_index = correctMaxBin;
}
}
我使用锯齿波测试了系统,我注意到倍频程错误仍然可见。87.307 Hz 到 ~190 Hz 它会产生高倍频程误差。G5 (783.991) 向上有时它显示一个八度更低。
以下是一些结果: 输入 | 结果 | 错误
F2 (87.307) - F4 (349.228) - 2 octaves higher
G2 (97.999)- G4 (391.995) - 2 octaves higher
A2 (110) - A3 (220) - an octave higher
D3 (146.832) - D4 (mostly) (293.665) and D3 - an octave higher
A3 (220) - A3 - Correct
A4 (440) - A4 - Correct
G5 (783.991) - G5 (mostly) and G4 (391.995) - an octave lower
A5 (880) - A5 - Correct
C6 (1046.502) - C6 - Correct
请帮我解决这个问题,因为这会严重影响系统对用户的最终反馈。