在 fft 中应用窗口函数的正确方法

Posted

技术标签:

【中文标题】在 fft 中应用窗口函数的正确方法【英文标题】:Correct way to apply window function in fft 【发布时间】:2015-03-29 14:09:40 【问题描述】:

我明白为什么我需要在 fft 中使用窗口函数,我录制了一个正弦波(16 位 pcm 格式),我有我想要分析的正弦波音频记录,我已经将麦克风音频录制成一个字节数组,将其转换回表示正弦波的样本数组,其值来自 [-1,1] - 值除以 32768。我是否需要在数组上应用具有值 [-1,1] 的窗口(除一)或者我是否需要将它应用到样本数组而不将其除以 32768?我在 SO 和 google 上查找了一些答案,找不到任何关于正确方法的解释。

【问题讨论】:

您将两个不相关的操作混为一谈 - 除以 32768 只是将 16 位有符号样本数据标准化为浮点 -1..+1 范围。可以在此之前或之后应用窗口函数,但之后在浮点域中执行它会更有意义。请注意,如果您只是想识别频率(根据您之前的问题),那么您甚至不需要除以 32768。 【参考方案1】:

linear-time-invariant 的一个特性是多个线性时不变系统级联的结果是相同的,无论操作执行的顺序如何(至少在理论上,实际上是过滤器等)可以有小的非线性,这会使结果根据顺序略有不同)。

从理论角度来看,对所有样本应用恒定比例因子可以看作是这样一个线性时不变系统。对于特定的计算机实现,缩放也可以被认为是近似线性时不变的,只要缩放不会引入显着的精度损失(例如,通过将数字缩放到浮点最小可表示值附近的值),也不会导致失真超出支持范围的缩放值。在您的情况下,简单地除以 32768 很可能不会引入明显的失真,因此可以认为是(近似)线性时不变系统。

同样,应用一个将每个样本乘以不同的窗口值的窗口,也可以看作是另一个线性时不变系统。

确定您拥有这样的级联线性时不变系统后,您可以在应用窗口之前或之后执行 32768 的缩放。

P.S.: 正如 Paul 在 cmets 中提到的,如果您要使用浮点数,您可能需要先执行从 16 位字到浮点数(无论是否缩放)的转换点值之后。尝试在定点算术中执行缩放可能会比必要的更复杂,并且如果不仔细执行,可能会损失我上面提到的精度。

【讨论】:

以上是关于在 fft 中应用窗口函数的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

非常窄的 FFT 窗口函数?

快速傅立叶变换应用窗口和重叠

错误结果绘图窗口 FFT

为啥 VS2015 调试器不能在监视窗口中正确显示函数地址?

如何在matlab的powergui里面进行fft分析

FFT窗口大小的意义