2

所以我正在尝试构建一个 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. 我的方法至少从根本上是正确的,还是我完全是在错误的树上吠叫?

如果这有助于回答我的问题,我很乐意展示我的任何代码,但其中有很多,所以我想我会选择性地这样做,而不是全部发布。

4

1 回答 1

2

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

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

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

附加提示:

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

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

我目前获得的表现会是我将获得的最好的吗?或者看起来我一定是个愚蠢的人,因为可以实现更快的速度?

它接近最佳,但您正在浪费所有 CPU 能力来估计高度冗余的数据,而没有给识别器留下任何 CPU 能力。

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

在考虑了我的回答后,您可能会重新考虑您的方法。

于 2014-01-30T06:28:36.577 回答