2013-03-22 54 views
2

所以我试图建立一个android应用程序,它作为一个实时音频分析器,作为一个项目的先驱,将涉及检测和过滤出某些声音。如何从android上的实时FFT获得最准确的音频数据?

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

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

看来这不会发生在智能手机上。事情是,我不确定我应该减少哪些计算参数,以便让我的Galaxy Nexus易于处理,同时仍然保持尽可能多的质量。最终我想要使用灵敏度更好的外置麦克风。

我认为这将涉及到移动窗口不止一个采样FFT之间的样本,但我不知道在什么时候,这会变得更加不利于精度/别名/不管只是在较小的窗口上做FFT,或者如果我忽略了第三种选择。

由于我使用libgdx本地实现的KissFFT,我似乎能够在44100个采样点之间进行30-42个44100个元素FFT的处理,并且仍然具有响应性(意味着缓冲区从线程AudioRecord.read()的填充速度比fft的线程耗尽速度要快)。

所以我的问题是:

  1. 可能目前我得到的只是表现是最好的,我会得到什么?还是看起来像我一定是愚蠢的,因为更快的速度是可能的?
  2. 我的方法至少是基本正确的,还是我在完全错误的树上吠叫?

我很乐意展示我的任何代码,如果这可以帮助回答我的问题,但有很多,所以我想我会选择性地做,而不是发布这一切。

+0

您还应该每次使用窗口函数过滤矩形窗口,例如hanning或hamming窗口以获得更好的准确性。当然这也会减慢执行速度 – SztupY 2013-03-22 23:09:27

+0

你的频率分辨率要求是什么?你实际上是否能够一次显示你从64k FFT中获得的32k输出样本?我问,因为考虑到缓存因素,FFT会变得效率低下,并且通常在现代x86 CPU上这一点大约为32k-64k,所以对于手机或平板电脑来说,这可能要低得多。因此,降低FFT大小,同时降低频率分辨率,可能确实会增加吞吐量。 – 2013-03-23 02:02:17

+0

“最准确”是没有意义的。您需要定义您的实际精度需求,并进行时间频率平衡。音频处理通常在比1000mS短得多的块上完成,可能只有25%到50%的重叠。 – hotpaw2 2013-03-24 00:35:39

回答

2

如果我俯瞰

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

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

附加提示:

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

  • 原始FFT输出很难识别“嗅探/嘴巴咀嚼”,经典识别器由HMM或人工神经网络组成,它们处理MFCC及其三角洲的序列。

可能目前我得到的只是表现是最好的,我会得到什么?还是看起来像我一定是愚蠢的,因为更快的速度是可能的?

它接近最好,但是您正在浪费所有的CPU功率来估计高度冗余的数据,而不会为识别器留下CPU电源。

我的方法是至少从根本上纠正或者我完全错误地吠叫树?

考虑我的答案后,你可能会重新考虑你的方法。

相关问题