AurioTouch和FFT用于乐器调音器

3
我正在尝试编写一个简单的调谐器(不是又一个调音应用程序),并查看AurioTouch示例源代码(有人尝试过注释这段代码吗?)。
我的担忧是,当查看频率域图时,aurioTouch似乎并没有真正很好地工作。我在乐器上演奏一个音符,但我没有看到一个有序、小的一组频率,只有一个适当频率的字符串峰值。
有人使用过aurioTouch足够了解底层代码是否可行,还是它只是一个粗糙的示例?
我有其他选择,可以使用FFTW或KISS FFT。有人对此有任何经验吗?
谢谢。

您可以在这里找到一个很好的示例 http://demetrimiller.com/2011/01/25/pitch-detection-in-ios-4-x/ - user1733304
4个回答

9

你期望的不对!

这并不是库的错

无论库是否正确生成它,你都在寻找一种在现实声音中很少存在的模式。只有一个完美的正弦波,通过电子方式产生,才会在频率图中产生均匀的离散“尖峰”。如果你不相信,请在Winamp或媒体播放器中启动“频谱分析器”可视化工具。这与PC无关。

真实的声波是复杂的生物

在你的脑海中想象一个锯齿形或方波。那些波浪上的急转弯或点,对于FFT或甚至是真正的傅里叶来说,看起来就像是许多更高的谐波。如果你曾经在示波器上看到过真正的“方波/锯齿形”,或者甚至是一个仪器产生的“正弦波”,你会发现在一个音符中有所有尖锐的角落和缝隙(如果你没有示波器,只需在Audacity中放大波形 - 放大得越多,你所看到的高音就越多)。没错,这些偏差都算作频率。

有时在频谱分析中,很难区分一个音符和整个管弦乐队之间的差异。

但我听到了单音!

那么耳朵是如何做到的呢?它考虑了整个波形。然后你的低级大脑欺骗你的高级大脑,告诉它输入的是一个音符,而不是一堆泛音。

你无法完全做到这一点,但可以通过“训练”来近似。

近似:构建一些智能

在乐器上演奏音符并“保存”频率图。对于几个频率范围的音符或更好地说所有音符都要这样做。

然后通过将该乐器的保存图表乘以2^(1/12)(或1/24用于1/4步)来插值填充音符的差距。

找出如何将它们存储在快速可搜索的数据结构(如BST或trie)中。只需返回“这有多接近”的得分即可识别匹配项。如果以不同的音量录入,则还必须根据频率比例进行识别匹配。

使用智能

下次你寻找该乐器的音符时,只需取出“听到”的频率图并在该数据结构中找到它。你可以记录几个制造不同波形的乐器并搜索它们。如果有背景声音或多个音符,请选择最接近的匹配项。然后,如果你想识别其他音符,请从采样的频率模式中“减去”找到的频率模式,反复操作。

你的声音无法使用此方法...

如果你曾经尝试通过吟唱来调音吉他,你就会知道调音器并不那么聪明。当然,有些乐器(尤其是人声)确实会在音高上漂移,产生一个不断变化的波形(即使没有人唱歌)。
你不必为了一个“简单”的调音器应用程序而完全变得花哨,但如果你不仅仅是要制作另一个调音器应用程序,我猜想你实际上想识别音符(例如,也许你想从广播中的歌曲自动生成midi文件;-)。
祝你好运。我希望你能找到一个可以完成所有这些工作的库,而不是自己动手。
编辑2017
请注意这个网页:http://www.feilding.net/sfuad/musi3012-01/html/lectures/015_instruments_II.htm。往下滚,有各种管风琴的频谱分析。有许多,许多倍频。如果你先用它们“训练”你的应用程序(就像告诉孩子,“这是单簧管的声音……”),这些都是可以检测出来的。

我也正在制作一个吉他调音器,你能帮我一下吗? - tryKuldeepTanwar

4
aurioTouch看起来很奇怪,因为频率轴是线性的。当x轴不是对数刻度(传统上是log2)时,解释FFT输出非常困难。
如果您无法使用aurioTouch的整数FFT,请查看我的库:http://github.com/alexbw/iPhoneFFT。它使用双精度,支持多种窗口类型,并实现了Welch's method(在时间上观察时应该会给您更稳定的光谱)。
@zaph,FFT确实计算了真正的离散傅里叶变换。它只是一种利用数字信号的位表示的高效算法。

谢谢!我会查看你的代码。你知道aurioTouch是否是Ooura FFT的衍生品吗? - mahboudz
1
aurioTouch实现了自己的FFT。 当我说“Ooura的FFT”时,我指的是教授写的代码:http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html。我的项目是对它的一个封装,使其(略微)更适合ObjC程序员使用。这两个代码使用的算法几乎肯定非常相似。据我所知,当使用2的幂长度信号时,原始FFT算法没有多少变体。 - alexbw
有没有一个示例Xcode项目展示如何使用iPhoneFFT?我似乎无法在我的项目中将其连接起来。 - Matthew

2

快速傅里叶变换(FFT)使用频率区间,区间的宽度基于FFT参数。要找到一个频率,您需要以至少是样本中最高频率两倍的速率对其进行采样。然后找到周期之间的时间。如果它不是纯频率,这当然会更难。


但是aurioTouch是否正确执行?另外,您说要找出周期之间的时间。如果我进行FFT,那么我就不必这样做,正如您所提到的那样,FFT会为我完成。我对FFT和音符的经验是一个bin将显示更高的值,这将是该音符的基频。我假设所有的音符都有一个容易识别的基频,否则我们的耳朵会拒绝它们作为走音。 - mahboudz
大家好,我也在尝试将auriotouch项目集成到我的应用程序中。我已经尝试了很长时间,但仍然无法解决问题。所以,请帮助我解决这个问题好吗?谢谢。 - The X-Coder
最好提出一个问题并提供你的代码,说明哪里出了问题。 - zaph
@Zaph:我有原始的auriotouch示例,根据我的需求进行了一定程度的修改。然后我创建了一个名为aurioview的新项目,并尝试将auriotouch集成到aurioview中。但是在运行aurioview时,没有错误,但也没有输出。如果可以的话,我可以发送给您我的示例项目,以便您自己检查可能的真正问题是什么,您觉得可以吗? - The X-Coder
@Ajit 抱歉,但我现在真的没有时间去做那件事。 - zaph
显示剩余2条评论

0

我正在使用Ooura FFT计算加速度计数据的FFT。但我并不总是得到正确的频谱。由于某种原因,Ooura FFT会产生完全错误的结果,其频谱幅值在所有频率上都达到10^200的数量级。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接