用于基音检测的FFT

时间:2011-06-27 01:54:07

标签: fft pitch

我最近使用FFT进行音高检测,我注意到,尽管音符是正确的(例如C,D#等),但是有很多音符都在错误的八度音程中(例如E2被归类为E3 ,C3被归类为C4,总是八度音阶。)

为什么会这样?我的算法是在计算FFT区间后,得到具有最大强度的区间并计算它是哪个频率。

对此有何帮助?谢谢!

4 个答案:

答案 0 :(得分:2)

两个想法: -

  1. 如果您的输入和算法总是与您的预期完全相差1个八度,那么您不能只是认为您已经校准过并且总是减去一个八度音程吗?

  2. 当你拿一把吉他弦时,你总是会得到一个高度谐波(二次谐波),这个声音非常响亮 - 大约和自然(一次谐波)一样大。接下来你得到1个八度音程七音(三次谐波),但八度音调非常明显。

答案 1 :(得分:1)

对我来说听起来像是谐波。格雷格的尖锐问题似乎正在走上正轨。

如果这是真的,你可以尝试找到所有桶的统计中位数并找到最接近的,而不是找到统计模式(正如你现在所做的那样)。

如果您看到输出变化,您还可以进行时间平滑(平均值随时间变化)。

我知道吉他调音师做了好几件事,而且间歇性地出现错误。这是一个混乱的业务:)

说到实时采样,根据您的样本来源,有很多异常需要考虑,可能会给您带来意想不到的结果:

  • 声音中的泛音
  • 声音中听不到声音

这些会显示在您的数据中,但您可能无法听到它们。如果你试图匹配多个音调或和弦,你的工作将更加复杂。

答案 2 :(得分:0)

在决定将音高放入哪个音高时,尝试向每个音频添加一定比例的音频量,该频率是频率的3倍(例如,将1320Hz音频的振幅的一部分加到440Hz音频)。在大多数仪器上,A440可能具有880Hz,1320Hz,1760Hz,2200Hz,2640Hz等的重要分量.A880可能具有880Hz,1760Hz和2640Hz,但不会有明显的1320Hz分量(也不是2220Hz)物)。因此,如果您的代码试图确定音符是A440还是A880,那么查看三次谐波桶(或其他奇次谐波)可能会提供一个有用的线索。

答案 3 :(得分:0)

八度检测可能非常棘手,特别是对于缺少基本谐波和/或其他谐波的复音信号。假设您正确地检测到“音调”而不仅仅是“谐波”(请参阅​​下面的维基百科链接),那么您可以使用我开发的八度音检测算法。

为了对PitchScope Player进行音高检测,我决定采用这样的2阶段算法:a)首先检测音符的ScalePitch - 'ScalePitch'有12个可能的音高值:{E,F ,F#,G,G#,A,A#,B,C,C#,D,D#}。并且在确定音符的ScalePitch和时间宽度之后,b)然后通过检查4个可能的Octave-Candidate音符的所有谐波来计算该音符的Octave(基波)。

我的音高检测应用程序PitchScope Player的完整C ++源代码和可执行文件位于GitHub(下面的链接),您可以编译并逐步查看它,看看我的Octave Detection算法是如何工作的。

您可能希望关注文件FundCandidCalcer.cpp中的FundCandidCalcer :: Calc_Best_Octave_Candidate()功能,以便在C ++中查看该算法。下图还粗略地介绍了如何计算Octave。

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

https://github.com/CreativeDetectors/PitchScope_Player

下图演示了Octave Detection算法,我开发该算法,一旦确定了该音符的ScalePitch,就选择正确的Octave-Candidate音符(即正确的基本音符)。

enter image description here