2012-07-19 140 views
6

虽然我在这个网站上处理音高检测的概念有很多问题......他们都处理这个神奇的FFT与我不熟悉。我正在尝试构建需要实施基音检测的Android应用程序。我完全不理解用于执行此操作的算法。虚拟音频的频率/音调检测

那不可能是难道可以吗?毕竟,Android市场上有大约80亿个吉他调谐器应用程序。

有人可以帮忙吗?

+2

您需要对快速傅立叶变换有一些基本的了解才能实现您所要求的。如果你正在寻找一个Java FFT库,我无法想象它会很难找到一个。除非你想学习一些信号处理,否则我建议寻找一个吉他调音器库。如果没有基本的理解,FFT会很难实现。 – Tucker 2012-07-19 02:29:09

回答

3

快速傅立叶变换将函数从时域变为频域。因此,代替f(t)其中f是您从麦克风获得的信号,而t是该信号的时间索引,您将获得g(θ),其中g是FFT的f,而θ是频率。一旦你有g(θ),你只需要找到哪个θ振幅最高,这意味着“最响亮”的频率。这将是你正在拾音的主要音调。至于实际实现的FFT,如果你谷歌“快速傅里叶变换示例代码”,你会得到一堆的例子。

+1

此[示例](http://stackoverflow.com/a/2065693/230513)可能对测试有用。 – trashgod 2012-07-19 02:28:45

+1

我发现了一堆样本,都需要值的数组,我不知道如何获取或他们的意思。尽管我们正在那里。在正确的邮政编码中是[this](http://introcs.cs.princeton.edu/java/97data/FFT.java.html)? – brainmurphy1 2012-07-19 02:44:15

+1

@ brainmurphy1该链接看起来是正确的。通过从麦克风读取输入来获取数组。我从来没有这样做过,但谷歌说你想[AudioRecord](http://www.jarvana.com/jarvana/view/com/google/android/android/2.2.1/android-2.2.1-javadoc .jar!/android/media/AudioRecord.html)类,这里是一个例子:http://www.androiddevblog.net/android/android-audio-recording-part-2 – 2012-07-19 02:52:21

12

FFT并不是真正实现音高检测或音高跟踪的最佳方法。一个问题是最大的频率并不总是基频。另一个原因是,FFT本身需要相当大量的数据和处理才能获得调谐乐器所需的分辨率,因此它看起来响应速度很慢(即延迟)。还有一个问题是,FFT的结果必须直观地处理:你得到一个复数的数组,你必须知道如何解释它们。

如果你真的想使用FFT,这里是一个办法:

  1. 低通的信号。这将有助于防止噪音和高次谐波产生虚假结果。可以想象,你可以跳过这一步,而是将结果加权到FFT的较低值。对于一些基频较强的乐器,这可能不是必需的。
  2. 窗口您的信号。 Windows应该至少有4096个大小。越大越好,因为它给你更好的频率分辨率。如果你太大,最终会增加你的计算时间和延迟。 hann功能是您窗户的不错选择。 http://en.wikipedia.org/wiki/Hann_function
  3. 尽可能频繁地FFT窗口信号。即使重叠的窗户也很好。
  4. FFT的结果是复数。使用sqrt(real^2 + imag^2)查找每个复数的大小。具有最大幅度的FFT阵列中的索引是具有峰值频率的索引。
  5. 您可能想要平均多个FFT以获得更一致的结果。

你如何计算指数的频率?那么,假设你有一个大小为N的窗口。在FFT之后,你将有N个复数。如果您的峰值是第n个,而您的采样率是44100,那么您的峰值频率将接近(44100/2)* n/N。为什么接近?那么你有(44100/2)* 1/N的错误。对于4096的档位大小,这大约为5.3 Hz - 在A440处很容易听到。您可以通过以下方式来改进:1.考虑阶段(我只描述了如何考虑量级),2。使用更大的窗口(这将增加等待时间和处理要求,因为FFT是N对数N算法),或者3.使用更好的算法,如YIN http://www.ircam.fr/pcm/cheveign/pss/2002_JASA_YIN.pdf

您可以跳过窗口步骤并将音频分成离散块无论您想分析多个样本。这相当于使用一个方形窗口,它可以工作,但是在结果中可能会得到更多噪音。

BTW:许多这些调谐器应用程序许可代码形式的第三方,如z平面和iZotope。

更新:如果你想要C源代码和完整的FFT方法教程,我已经written one。该代码编译并在Mac OS X上运行,并且应该可以轻松转换为其他平台。它的设计不是最好的,但它的设计很容易理解。

+1

这看起来正是我所需要的,但它对我来说毫无用处,因为我不知道“低通”,“开窗”和“汉恩函数”是什么。 (尽管链接,我仍然不明白它如何适用。)上述建议可能会帮助谁知道更多,但我问这个问题,因为我完全不知道他们。 – brainmurphy1 2012-07-20 00:26:49

+0

窗口:http://en.wikipedia.org/wiki/Window_function – 2012-07-20 01:52:51

+0

对于低传球我建议一个替代方案,但如果你不知道它是什么,你可以谷歌它,并提出另一个问题。这不是一个可以很容易地作为另一个问题的子回答覆盖的问题。 – 2012-07-20 01:54:20