如何从Android上的实时FFT获得最准确的音频数据?

时间:2013-03-22 23:05:43

标签: android real-time fft audio-recording kissfft

因此,我正在尝试构建一个Android应用程序,它充当实时音频分析器,作为项目的前身,将涉及检测和过滤掉某些声音。

所以我认为我已经完成了离散傅立叶变换的基础知识,但是我不确定进行实时频率分析的最佳参数应该是什么。

我得到的印象是,在理想情况下(无限的计算能力),我会从我从AudioRecord类获得的44100样本/秒PCM流中获取所有样本并将它们放入44100元素fifo“窗口” (填充到2 ** 16,0和可能是逐渐变细的函数?),每次有新样本进入窗口时都会运行FFT。这样(我想),给我的频谱为0 - ~22 KHz更新44100每秒一次。

似乎这不会发生在智能手机上。问题是,我不确定我应该减少哪些计算参数,以使其在我的Galaxy Nexus上易于处理,同时仍然保持尽可能多的质量。最后我想使用灵敏度更高的外置麦克风。

我认为它将涉及在采用FFT之间移动窗口多个样本,但我不知道在什么时候这对精度/混叠/不仅仅是在较小的窗口上进行FFT,或者如果有是我忽略的第三种选择。

使用libgdx本机实现的KissFFT,我似乎能够在每44100个样本的30-42 44100个元素FFT之间进行某些操作,并且仍然具有响应性(意味着缓冲区从线程中填充) AudioRecord.read()的填充速度并不比执行fft的线程可以耗尽它的速度快。

所以我的问题是:

  1. 我目前的表现能否达到最佳状态?或者看起来我必须是愚蠢的东西,因为更快的速度是可能的?
  2. 我的方法至少从根本上是正确的,还是我完全在错误的树上狂奔?
  3. 我很乐意展示我的任何代码,如果这有助于回答我的问题,但是有很多代码,所以我认为我会选择性地这样做,而不是全部发布。

1 个答案:

答案 0 :(得分:2)

  

如果有第三种选择,我会忽略

是:同时执行这两项操作,缩小FFT大小以及增大步长。在评论中你指出你想要检测“用嘴嗅闻/咀嚼”。所以,你想要做的是类似于语音识别的典型任务。在那里,您通常以10ms的步长提取特征向量(意味着每441个样本的Fs = 44.1kHz),并且要变换的信号窗口大约是步长大小的两倍,因此20ms产生2 ^ X FFT大小为1024个样本(确保选择FFT大小为2的幂,因为它更快)。

窗口大小的任何增加或步长的减小都会增加数据,但主要是增加冗余。

其他提示:

  • @SztupY正确地指出你需要在FFT之前“窗口”你的信号,通常是汉明 - wondow。 (但这不是“过滤”。它只是将每个样本值乘以相应的窗口值而不累积结果)。

  • 原始FFT输出几乎不适合识别“用嘴嗅闻/咀嚼”,经典识别器由处理MFCC及其增量序列的HMM或ANN组成。

  

我目前的表现能否成为我将获得的最佳表现?或者看起来我必须是愚蠢的东西,因为更快的速度是可能的?

它接近最好,但是你浪费了所有的CPU能力来估算高度冗余的数据,不会给识别器留下任何CPU能力。

  

我对此的处理方法至少从根本上是正确的,还是我完全吠叫错误的树?

在考虑我的回答之后,你可能会重新思考你的方法。