我正在探索语音识别和DSP,因此我想在我的智能手机上实现一个简单的声音频率分析仪(我有一部iPhone和一部运行Android的三星Nexus S)。我以前在Matlab中完成了基本的DSP。
根据我的理解,我需要执行FFT来获得信号的基频。
现在,我想以44100 Hz的频率对麦克风进行采样。如果我使用样本大小为512且重叠率为50%的滑动窗口,则意味着我需要每256个样本进行一次FFT,或者0.00580秒。
这个比率看起来真的很高,特别是如果我用Java编写Android版本。我的智能手机能够处理这个速度吗?我知道你可以在Android上使用C / C ++编程,但我想暂时保留它。
答案 0 :(得分:9)
执行实数到复数FFT需要~5 / 2 n lg n个浮点运算(加法和乘法)。在你的情况下,n = 512,所以:
flops per fft ~= (5/2) * 512 * 9 = 11520
因此,每秒172个fft每秒需要大约200万个浮点运算。这听起来很多,但实际上并不是那么多。典型的armv7级智能手机的硬件每秒能够进行数亿或数十亿次浮点运算。
但请注意,您需要精心编写的高性能FFT;写得不好的FFT是众所周知的低效率。在iPhone上,您可以使用Accelerate框架(内置于操作系统中,并在SDK中提供),它提供了一组很好的FFT功能;我不确定Android上有哪些功能。
答案 1 :(得分:5)
对于iPhone,iOS的Accelerate框架可以按照CPU时间的1%(精确百分比取决于设备型号和FFT数据类型)执行您指定的所有FFT。
对于Android,您可能非常想考虑使用NDK本机库进行处理器密集型数值计算。
另请注意,FFT会为您提供峰值频率,但不一定包括基频或音调频率。
ADDED:这个Java benchmark web page表明Android手机能够在5到50多个MFlops的范围内使用Java进行精心编写的矩阵数学运算。精心编写的FFT应该与MFlops的性能范围大致相同。 @Stephan Cannon发布了您的规格可能需要2 MFlops的订单。
答案 2 :(得分:3)
您的Android设备将能够处理这个问题。我已经编写了几年前在Windows Mobile设备上运行的基于FFT的实时频率分析仪(使用纯C#),这些设备的处理器比当前的Android设备差得多。 FFT计算成本最高的方面是trig函数,由于你使用的是固定大小的窗口,你可以用预先计算的查找表轻松替换trig函数调用。
答案 3 :(得分:1)
另外,您可以通过降低采样率来减少计算时间。语音在8 kHz以上没有太多能量,因此在进行任何FFT之前,您可能会将音频下采样到16 KHz,而不会损失太多精度。在16 kHz时,您的FFT会更小,速度更快。
Wikipedia claims 16 kHz是桌面应用中语音识别的标准采样率。
(我意识到这并没有回答OP的问题,但我认为,鉴于他的申请,对他来说可能会有所帮助。)