我最近使用FFT进行音高检测,我注意到,尽管音符是正确的(例如C,D#等),但是有很多音符都在错误的八度音程中(例如E2被归类为E3 ,C3被归类为C4,总是八度音阶。)
为什么会这样?我的算法是在计算FFT区间后,得到具有最大强度的区间并计算它是哪个频率。
对此有何帮助?谢谢!
答案 0 :(得分:2)
两个想法: -
如果您的输入和算法总是与您的预期完全相差1个八度,那么您不能只是认为您已经校准过并且总是减去一个八度音程吗?
当你拿一把吉他弦时,你总是会得到一个高度谐波(二次谐波),这个声音非常响亮 - 大约和自然(一次谐波)一样大。接下来你得到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音符(即正确的基本音符)。