FFT 的返回值(系数)的单位是啥?

Posted

技术标签:

【中文标题】FFT 的返回值(系数)的单位是啥?【英文标题】:What is the unit of the return values (coefficients) of an FFT?FFT 的返回值(系数)的单位是什么? 【发布时间】:2013-07-26 13:09:33 【问题描述】:

我的应用程序对原始音频信号执行 FFT(所有麦克风读数都是 values 中的 16 位整数值,即 1024 个单元格)。它首先根据 16 位对读数进行归一化。然后提取频率400Hz的幅度。

int sample_rate = 22050;
int values[1024];
// omitted: code to read 16bit audio samples into values array

double doublevalues[1024];
for (int i = 0; i < 1024; i++) 
    doublevalues[i] = (double)values[i] / 32768.0; // 16bit


fft(doublevalues); // inplace FFT, returns only real coefficients

double magnitude = 400.0 / sample_rate * 2048;
printf("magnitude of 400Hz: %f", magnitude);

当我尝试这个并生成一个 400Hz 信号来查看 magnitude 的值时,当没有 400Hz 信号时它在 0 左右,当有 400Hz 信号时它会上升到 30 或 40。

magnitude 字段的单位或含义是什么?令我惊讶的是它大于 1,即使我将原始信号标准化为介于 -1..+1 之间。

【问题讨论】:

幅度在这里只是一个double,与信号无关 好的,那我怎么知道这能涨多远呢?那么可能值的范围是多少? 【参考方案1】:

这取决于您使用的是哪种 FFT,因为在缩放方面有不同的约定。最常见的约定是输出值按 N 缩放,其中 N 是 FFT 的大小。因此,1024 点 FFT 的输出值将是相应输入值的 1024 倍。更复杂的情况是,对于实数到复数的 FFT,人们通常会忽略 FFT 的对称上半部分,这很好(因为它是共轭对称的),但如果这样做,则需要考虑 2 倍。

FFT 缩放的其他常见约定是 (a) 不缩放(即 N 的因子已被移除)和 (b) sqrt(N),它有时用于 FFT 与 IFFT 的对称缩放行为(sqrt(N ) 在每个方向)。

由于 sqrt(1024) == 32 您可能正在使用具有 sqrt(N) 缩放的 FFT 例程,因为对于单位幅度正弦波输入,您似乎看到了大约 30 的值。

【讨论】:

好的。我使用只返回真实值的真实 FFT。我测试了我是否得到了回应。如果我将扬声器移到麦克风旁边,得到 30 到 40 之间的值让我感到惊讶。不应该高很多吗? 1024 意味着原始信号中的频率非常响亮,对吧? 您应该阅读 FFT 例程的文档,因为每个文档都不相同。 我输出的幅度是否也取决于信号的音量? 是的,FFT 输出的 幅度 与输入的幅度成正比(对于任何给定频率)。 保罗 R 是正确的。还要记住,在计算出 FFT 如何缩放输入样本数据之后,首先存在输入样本如何缩放麦克风拾取的声音的问题。这将取决于麦克风本身的灵敏度以及在移动/PC/其他设备上设置的增益设置。因此,每台设备上 400Hz 峰值的幅度都会有所不同。您的标准化将标准化整个声音,而不仅仅是 400hz 分量。

以上是关于FFT 的返回值(系数)的单位是啥?的主要内容,如果未能解决你的问题,请参考以下文章

FFT 深夜摸鱼小笔记

luogu3803 多项式乘法 (FFT)

[uoj#34] [洛谷P3803] 多项式乘法(FFT)

FFT(快速傅里叶变换)

试图计算 PostgreSQL 中两个 lat-lng 点之间的距离 - PostgreSQL earth_box(ll_to_earth) 返回值的单位是啥?

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