虽然我在这个网站上有很多关于音高检测概念的问题......但它们都处理了我不熟悉的神奇的 FFT 。我正在尝试构建一个需要实现音调检测的Android应用程序。我完全不了解用于执行此操作的算法。
难道不能吗?毕竟,Android市场上有大约80亿个吉他调谐器应用程序。
有人可以帮忙吗?
答案 0 :(得分:13)
FFT实际上并不是实现音高检测或音高跟踪的最佳方式。一个问题是最响亮的频率并不总是基频。另一个原因是FFT本身需要相当大量的数据和处理才能获得调谐仪器所需的分辨率,因此响应速度似乎很慢(即延迟)。另一个问题是FFT的结果必然是直观的:你得到一系列复数,你必须知道如何解释它们。
如果你真的想使用FFT,这里有一种方法:
如何计算指数的频率?好吧,假设你有一个大小为N的窗口。在FFT之后,你将有N个复数。如果您的峰值是第n个,并且您的采样率是44100,那么您的峰值频率将接近(44100/2)* n / N.为什么附近?你有错误(44100/2)* 1 / N.对于4096的箱子,这大约是5.3Hz - 在A440处容易听到。您可以通过以下方面进行改进:考虑到相位(我只描述了如何考虑幅度),2。使用更大的窗口(这将增加延迟和处理要求,因为FFT是N Log N算法),或3.使用更好的算法,如YIN http://www.ircam.fr/pcm/cheveign/pss/2002_JASA_YIN.pdf
您可以跳过窗口步骤,只需将音频分解为您要分析的多个样本的离散块。这相当于使用方形窗口,但是在结果中可能会产生更多噪音。
BTW:许多调谐器应用程序许可代码形成第三方,例如z-plane和iZotope。更新:如果你想要C源代码和FFT方法的完整教程,我written one。该代码在Mac OS X上编译和运行,并且应该可以很容易地转换为其他平台。它的设计并不是最好的,但它的设计很容易理解。
答案 1 :(得分:4)
快速傅立叶变换将函数从时域更改为频域。因此,f(t)
而不是f
,而t
是从麦克风获取的信号而g(θ)
是该信号的时间索引,而g
位于f
} {是θ
的FFT和g(θ)
是频率。获得θ
之后,您只需找到幅度最高的{{1}},即“最响”的频率。这将是你正在接受的声音的主要音调。
至于实际实现FFT,如果你谷歌“快速傅里叶变换示例代码”,你会得到一堆例子。