2016-11-11 84 views
0

我正在创建语音培训应用程序,并使用FFT将信号从时域转换到频域。在应用FFT之前,我使用blackman-harris窗口对信号进行了窗口化。然后我使用谐波产物谱来提取基频。最低频率是F2(87.307 Hz),最高频率是C6(1046.502 Hz)。 FFT长度为8192,采样频率为44100 Hz。如何解决谐波积谱中的八度误差?

要修复八度误差,我应用了规则here;

 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赫兹~190赫兹,它给八度高错误。 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 

请帮我解决这个问题,因为这会严重影响系统对用户的最终反馈。

回答

0

当我从和弦上检测到音调和八度音时,我用了一些不同的方法。为了识别包含“音调”的谐波,我选择了使用对数间隔的修改后的DFT,而不是FFT。

我还决定使用两阶段算法来检测音高,它决定了第二阶段后面的八度(以及隐含的基频)。算法是这样工作的:

a)首先检测主音符的ScalePitch - 'ScalePitch'有12个可能的音高值:{E,F,F#,G,G#,A,A#,B,C ,C#,D,D#}。 b)然后通过检查4种可能的八度候选音符的所有谐波来计算该音符的八度音(基频)。

八度检测可能非常棘手,特别是在缺少基本谐波和/或其他谐波的复音信号上。但是,即使缺少一些谐波,我的算法也可以工作。您可能需要编译并逐步通过GitHub上的PitchScope Player的Windows代码来查看我如何确定八度。

您可能想要关注FundCandidCalcer.cpp文件中的FundCandidCalcer :: Calc_Best_Octave_Candidate()函数,以查看C++中的八度检测算法。

https://github.com/CreativeDetectors/PitchScope_Player

https://en.wikipedia.org/wiki/Transcription_(music)#Pitch_detection

下图展示了我发展到选择正确的倍频候选音符(即正确的基础),八度检测算法一旦ScalePitch和谐波为音符已经确定。

enter image description here

+0

我正在做单音音调..我会试试看 – Giggity