【问题标题】:How to fix octave errors in harmonic product spectrum?如何修复谐波产品频谱中的倍频程误差?
【发布时间】:2016-11-11 09:21:01
【问题描述】:

我正在创建一个语音训练应用,并使用 FFT 将信号从时域转换到频域。在应用 FFT 之前,我已经使用 blackman-harris 窗口对信号进行了窗口化。然后我使用谐波产品频谱来提取基频。最低频率为 F2 (87.307 Hz),最高频率为 C6 (1046.502 Hz)。 FFT 长度为 8192,采样频率为 44100 Hz。

为了修复八度音阶错误,我应用了here by 提到的规则;

     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

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

【问题讨论】:

    标签: c# fft pitch-tracking


    【解决方案1】:

    当我从 MP3 录音的 复音 信号中检测音高和八度时,我使用了一些不同的方法。为了识别构成“音高”的谐波,我选择使用对数间隔的改进型 DFT,而不是 FFT。

    我还决定使用双阶段算法来检测音高,这在第二阶段后期确定了八度音程(以及隐含的基频)。该算法的工作原理如下:

    a) 首先检测主音的 ScalePitch -- 'ScalePitch' 有 12 个可能的音高值:{ E, F, F#, G, G#, A, A#, B, C, C#, D, D# } .在确定了一个音符的 ScalePitch 和 Time-Width 之后,

    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

    下图演示了八度检测算法,一旦确定了该音符的音阶和泛音,我开发该算法以选择正确的八度候选音符(即正确的基本音)。

    【讨论】:

    • 我正在研究单声道音高。我会试试看
    猜你喜欢
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 2017-09-03
    • 2020-10-27
    • 2022-08-16
    • 1970-01-01
    相关资源
    最近更新 更多