我正在开发一个简单的Web应用程序,该应用程序允许用户调整他/她的吉他。我是信号处理方面的真正初学者,因此,如果我的问题不合适,请不要对我太苛刻。功能。但是,仍有改进的空间。现在,我将原始PCM发送到FFT算法,但我当时认为可能有一些前置/后置算法/滤波器可以改善检测效果。你能建议什么吗?
我的主要问题是,当它检测到某个频率时,它会显示该频率1-2秒,然后跳至其他随机频率,然后再次返回,依此类推,即使声音是连续的。
如果有人对此有经验,我也会对其他任何类型的优化感兴趣。

#1 楼

我猜它得到的其他频率是基波的谐波?就像您在演奏100 Hz,而是拾取200 Hz或300 Hz一样?首先,应将搜索空间限制在吉他可能会出现的频率范围内。找到您可能需要的最高基频并将其限制在此范围内。

如果基频的幅度低于谐波(或完全丢失),则自相关将比FFT更好地找到基频。这不是吉他的问题):



您还可以尝试加权较低的频率以强调基音并最大程度地减少谐波,或者使用类似这样的调峰算法然后选择最低的频率。

此外,在应用FFT之前,应先对信号加窗。您只需将其乘以窗口函数即可,该函数会逐渐减小波形的开始和结束以使频谱更清晰。然后,您会得到频率分量的高尖峰而不是宽的尖峰。取光谱的对数,然后将抛物线拟合到峰和两个相邻点,并找到抛物线的真实峰。不过,您可能不需要那么高的准确性。

这是我所有示例的Python代码。

评论


$ \ begingroup $
这就是我想要的,很好的回答,谢谢!
$ \ endgroup $
–瓦伦丁·拉杜(Valentin Radu)
2011年10月13日下午13:54

$ \ begingroup $
乘以锥形的窗函数实际上会抹去信号中的任何频谱线,从而使它们更宽。但是,它可以为您提供的是动态范围,它使您可以在存在高功率干扰音的情况下识别例如低功率频谱线。
$ \ endgroup $
–Jason R
2011-10-13 14:10

$ \ begingroup $
@JasonR考虑到此功能旨在在大功率干扰音的概率确实很低的环境中工作,您建议不要使用汉明窗更好吗?
$ \ endgroup $
–瓦伦丁·拉杜(Valentin Radu)
2011-10-13 14:32

$ \ begingroup $
我可以确认使用汉明窗使我更接近保持读数稳定的目标。现在,当我演奏A4时,大多数时候会获得440 Hz的频率,而很少见的是接近650 Hz的读数。我猜那些是谐波吗?另外,我不禁注意到,对于更高的频率,该应用程序可以正常工作,而对于更低的频率,该应用程序将开始失败。可能是因为我正在使用FTT来检测峰值幅度频率仓,而对于较低的频率,这并不总是根本吗?
$ \ endgroup $
–瓦伦丁·拉杜(Valentin Radu)
2011-10-13 15:53



$ \ begingroup $
@mindnoise:660 Hz不是440 Hz的谐波,而是220 Hz的谐波,或者是440之上的完美五分之一。可能是另一弦共振或失真或其他原因吗?如果您可以绘制FFT并进行查看,则找出这样的问题要容易得多。是的,低频可能会由于机械效应或模拟电路而被滤波并相对于高频被降低。
$ \ endgroup $
– Endolith
2011年10月13日15:56

#2 楼

音调与FFT的峰值幅度频率仓不同。音调是一种人类的心理声学现象。基音可能缺少或非常弱的基音(在某些语音,钢琴和吉他声音中很常见)和/或频谱中的许多有力的泛音使基音频率不堪重负(但仍被人听到为该基音) 。因此,任何FFT峰值频率检测器(甚至包括一些开窗和内插)都不是可靠的音高估计方法。

这个stackoverflow问题包括一些估计音高的替代方法的列表,这些方法可能会产生更好的结果。

添加:如果要对吉他声音进行此操作,请注意最低吉他弦实际上可能会产生轻微的不谐调泛音,使音高估计更加困难,因为人耳所听到的音高频率与泛音的约数(而不是弦的实际基本振动频率)更紧密相关。 />
添加#2:这个问题经常被问到,以至于我写了一篇较长的博客文章,主题是:http://www.musingpaw.com/2012/04/musical-pitch-is-not-just -fft-frequency.html

评论


$ \ begingroup $
刚刚访问(并评论了)您刚刚提到我们的博客。
$ \ endgroup $
–罗伯特·布里斯托-约翰逊
16-3-14在4:43

#3 楼

我花了很多年研究和弦音乐的音高检测-就像检测mp3录音中吉他独奏的音符一样。我还在Wikipedia上写了一个部分,简要介绍了该过程(请看下面链接中的“音高检测”小节)。

当在钢琴上按下一个键时,我们听到的不仅是声音振动的频率,而且是在不同的数学相关频率下发生的多种声音振动的组合。这种在不同频率下的振动合成的元素称为谐波或部分谐波。例如,如果我们按钢琴上的中音C键,则复合谐波的单个频率将从261.6 Hz开始作为基本频率,523 Hz为第二谐波,785 Hz为第三谐波,1046 Hz是4次谐波,等等。后面的谐波是基频261.6 Hz的整数倍(例如:2 x 261.6 = 523、3 x 261.6 = 785、4 x 261.6 = 1046)。

我使用一种改进的DFT对数变换,首先通过查找峰值电平的频率来检测可能的谐波(请参见下图)。由于我收集修改后的Log DFT数据的方式,因此不必对信号应用开窗功能,也不必进行加法和重叠。我创建了DFT,以便将其频率通道对数定位,以便直接与吉他,萨克斯风等音符产生谐波的频率对齐。

现在已经退休,我决定在一个名为PitchScope Player的免费演示应用程序中发布我的音高检测引擎的源代码。 PitchScope Player可在网上找到,您可以下载Windows的可执行文件,以查看我的算法在所选mp3文件上的作用。以下指向GitHub.com的链接将带您进入完整的源代码,您可以在其中查看我如何使用自定义对数DFT变换检测谐波,然后查找频率满足正确整数关系(定义“

我的音高检测算法实际上是一个两阶段过程:
a)首先检测到ScalePitch(“ ScalePitch”具有12个可能的音高值:{E,F,F#, G,G#,A,A#,B,C,C#,D,D#})
b)确定ScalePitch之后,通过检查4个可能的八度候选音符的所有谐波来计算八度。
该算法旨在检测和弦MP3文件中任何给定时刻的最主要音高(音符)。这通常与器乐独奏的音符相对应。那些对我的2级音高检测算法的C ++源代码感兴趣的人可能想从GitHub.com上SPitchCalc.cpp文件中的Estimate_ScalePitch()函数开始。 / CreativeDetectors / PitchScope_Player

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

下面是对数DFT的图像(由我创建C ++软件),进行3秒钟的吉他独奏,并录制和弦mp3录音。它显示了弹奏独奏时吉他上各个音符的谐波如何出现。对于此对数DFT的每个音符,我们可以看到其多个谐波垂直延伸,因为每个谐波将具有相同的时间宽度。确定音符的八度之后,我们便知道基本音的频率。



下图演示了八度音阶检测算法,一旦确定了该音阶的ScalePitch,我就会开发该算法来选择正确的八度音阶候选音符(即正确的基本音阶)。那些希望在C ++中看到该方法的人应该转到文件FundFandidCalcer.cpp中的Calc_Best_Octave_Candidate()函数,该文件包含在GitHub的源代码中。

评论


$ \ begingroup $
James,您的DFT音高检测器是否检测到基音缺失(或较弱)的音符?
$ \ endgroup $
–罗伯特·布里斯托-约翰逊
16年7月6日在0:28

$ \ begingroup $
是的,即使信号的“基音缺失(或弱)”,我的2级音高检测算法也可以检测到音符,这是2级音高处理的重要优势。当在对数DFT图表上看到的注释的时间宽度上执行八度检测时,在第二阶段确定基本面。由于此音高检测功能可在和弦mp3信号混乱的情况下工作,因此它将检测到缺少许多谐波的音符,包括基本音。我刚刚在“答案”中添加了第二张图,该图解释了我的八度检测算法。
$ \ endgroup $
–詹姆斯·保罗·米拉德(James Paul Millard)
16年7月6日在1:05