为啥我的 NAudio FFT 结果与 MATLAB 相差 4 倍?

Posted

技术标签:

【中文标题】为啥我的 NAudio FFT 结果与 MATLAB 相差 4 倍?【英文标题】:Why does my NAudio FFT result differ from MATLAB by a factor of 4?为什么我的 NAudio FFT 结果与 MATLAB 相差 4 倍? 【发布时间】:2018-06-11 21:15:38 【问题描述】:

以下 C# NAudio 代码与 MATLAB 产生的结果相差 4 倍。为什么会发生这种情况,其中一个是不正确的?

Complex[] tmp = new Complex[4];
tmp[0].X = 1.0f;
tmp[1].X = 0.5f;
tmp[2].X = 1.0f;
tmp[3].X = 0.25f;
tmp[0].Y = 0.0f;
tmp[1].Y = 0.0f;
tmp[2].Y = 0.0f;
tmp[3].Y = 0.0f;
FastFourierTransform.FFT(true, 2, tmp);

音频输出:

0.6875 + 0.0000i
0.0000 - 0.0625i
0.3125 + 0.0000i
0.0000 + 0.0625i

MATLAB 输出:

2.7500 + 0.0000i
0.0000 - 0.2500i
1.2500 + 0.0000i
0.0000 + 0.2500i

【问题讨论】:

我相信 matlab 的实现。要找到问题,也许您可​​以使用具有特定频率的较长信号,然后观察频谱。 【参考方案1】:

Discrete Fourier transform 及其逆需要一定的归一化,以便ifft(fft(x))==x。这种规范化的完成方式因实施而异。

在这种情况下,NAudio 似乎选择了与 MATLAB 不同的标准化。

MATLAB 使用最常见的归一化,其中k=0 处的fft(x) 等于sum(x),逆变换做同样的事情,但除以n(样本数)。这也是Wikipedia page for the DFT 中描述的等式。在这种情况下,逆变换匹配傅里叶级数的方程。

NAudio 似乎在前向变换中通过n 进行除法,因此在k=0 你有mean(x)

鉴于上述情况,您可以使用第一个频率区间(直流分量)来验证使用了什么归一化(假设有直流分量,如果信号为零意味着这将不起作用):如果直流分量等于所有样本值的总和,则使用“通用”归一化。在对称定义的情况下,它也可以等于总和除以sqrt(n),其中正向和逆变换进行相同的归一化。对于 NAudio,它将等于总和除以 n(即样本值的平均值)。通常,取直流分量并除以样本值的总和。结果q 是使用的规范化术语。逆变换应该有一个归一化项1/qn

【讨论】:

我认为这意味着两者都不正确,除非您确定某种电平校准,否则将 am 幅度图的绝对能量/功率与 2 种不同 FFT 算法计算的绝对能量/功率进行比较总是不明智的已经发生。这意味着我可以继续使用 NAudio,而无需对复杂的数据进行任何手动更正。 @AlexS:FFT 不计算能量或功率,它计算 DFT。只要您知道 FFT 算法使用的 DFT 的定义,您就可以从那里轻松计算能量/功率。请注意,只需查看频率 0 的输出,您就可以找出正在使用的归一化。 -- 我的意思是,在将单位添加到任何绘图之前,您需要知道您计算的内容... :) 谢谢,在这种情况下,您能否详细说明如何使用第一个频率箱 0 Hz(或 DC)确认归一化方法,我认为这将证明它们是相同的,并且答案将是完整的。 @Alex:我添加了一段关于如何检查规范化的内容。这是你的想法吗?

以上是关于为啥我的 NAudio FFT 结果与 MATLAB 相差 4 倍?的主要内容,如果未能解决你的问题,请参考以下文章

为啥不使用 Scipy 的 FFT 代码中的结果与 Scipy FFT 不相似?

如何使用 NAudio 对波形文件执行 FFT

序列的离散傅里叶变换(DFT)的来龙去脉并附利用MATLA的函数FFT()求序列的DFT的示例

NAudio FFT 返回所有频率的小而相等的幅度值

为啥我的 FFT 提供的可视化工具输出与 Windows Media Player 不同?

使用 Matlab FFT 计算的频谱对于不同长度的样本(点数相同但 Fs 不同)给出的结果不一致?