FFT 的窗口大小与数据长度
Posted
技术标签:
【中文标题】FFT 的窗口大小与数据长度【英文标题】:Window size vs data length for FFT 【发布时间】:2011-04-06 17:16:36 【问题描述】:我正在尝试对流式音频数据进行快速频谱分析以捕获元音(类似于 JLip-sync)。使用 PyAudio 在短时间内(0.0625 秒)以小块(1024)捕获语音数据。使用 numpy.fft 进行分析,并使用 numpy.hanning 窗口消除泄漏。我使用 4096*4 作为采样率(不是 44100 或 22050,也可以讨论;4096*4 最接近 22050)。
考虑到我感兴趣的频率(范围从 300 Hz 到 3000Hz),如何使用我正在寻找的数据长度和最小/最大频率来计算理想的窗口大小?
谢谢。
卡迪尔
【问题讨论】:
【参考方案1】:@卡迪尔:
在使用离散傅里叶变换(DFT 或 FFT)处理数据之前对数据进行窗口化的目的是尽量减少频谱泄漏,当您尝试对非循环数据进行傅里叶变换时会发生这种情况。
窗口化的工作原理是在序列的开始和结束处(而不是之前)将数据平滑地强制为零。缩短窗口会不必要地破坏信息。
因此,您的窗口长度应与样本序列的长度相匹配。例如,对于 1024 个样本,您的窗口长度应为 1024。
如果您要解析的最高频率是 3 KHz,请以不同的采样率使用 8192 个或更多样本,例如 16384 或 32768 个样本。
另外,尝试不同的 FFT 算法,不同的样本长度,不同的窗口,包括 Hann(汉宁),也可以尝试其他旁瓣衰减更好的窗口,如 Blackman-Harris 级数和 Kaiser-Bessel 级数等。
如果您的应用程序嘈杂,您可能必须在更好的噪声抑制窗口和更高的光谱分辨率窗口之间进行选择。因此,尝试不同的窗口是个好主意,这样您就可以找到最适合您的应用程序的窗口。
现在,写下每个设置的结果(即每个窗口、样本长度、采样率等),并寻找在多个设置中一致的结果。您将深入了解您的数据,并很有可能找到问题的答案。
你可以用 Matlab 做到这一点:http://www.mathworks.com/help/techdoc/ref/fft.html
或使用此在线 FFT 频谱分析仪:http://www.sooeet.com/math/fft.php
别忘了在这里发布你的结果。
【讨论】:
【参考方案2】:关键因素是您在频域中需要多少分辨率来区分不同的元音。分辨率为1 / T
,其中T
是FFT 窗口的持续时间。因此,如果您的采样时间为 62.5 毫秒,那么如果您的 FFT 与采样间隔(1024 个样本)的大小相同,那么您的最大分辨率为 16 Hz(即每个 FFT bin 的宽度为 16 Hz)。如果您使用较小的 FFT,那么显然您的分辨率会成比例地恶化,例如512 点 FFT 的分辨率只有 32 Hz。
【讨论】:
感谢您的回复。他们所说的“共振峰”通常具有大约 100 HZ 的间隔。即使有时重叠,它们的第二共振峰也有很大不同,在 1000 Hz 水平。所以我可能会下降到 128。如果我使用等于数据长度 (1024:1024) 的窗口大小,我会丢失任何东西吗? @Kadir:我认为 16 Hz 的分辨率就足够了——只要你能识别出各个谐波,然后使用这些信息来确定共振峰,那么你应该没问题。 再次感谢保罗。那就是问题所在。所有的“能量”似乎都处于高端。从理论上讲,我应该看到单个谐波,然后我可以识别共振峰,但我没有。我是否应该使用类似 256p 移动平均线的东西,因为我对大约一半频谱的 300 - 3000 Hz 频带感兴趣? @Kadir:首先你需要确保你的 FFT 工作正常。您还需要在 FFT 之前应用合适的窗口函数(例如 Hanning)。对于 FFT 的输出,您应该计算对数幅度 (10*log10(re*re+im*im)
) - 这应该会为您提供一个不错的功率谱,其幅度为 dB。以上是关于FFT 的窗口大小与数据长度的主要内容,如果未能解决你的问题,请参考以下文章
iOS 上的 fft numpy 风格以非两个数据长度的幂加速