如何获得 FFT 中每个值的频率?

Posted

技术标签:

【中文标题】如何获得 FFT 中每个值的频率?【英文标题】:How do I obtain the frequencies of each value in an FFT? 【发布时间】:2011-05-20 20:56:45 【问题描述】:

我有一个 FFT 结果。它们存储在两个double 数组中:一个实部数组和一个虚部数组。如何确定这些数组中每个元素对应的频率?

换句话说,我想创建一个数组来存储我的 FFT 的每个实部和虚部的频率。

【问题讨论】:

我在 C#.net 中完成。你能帮我吗? 如果您不了解 FFT 实部和虚部的相关性,那么您将不会得到任何有意义的结果,因此您应该寻找一些 FFT 和信号处理教程来理解如何解释结果。我认为无论您将其用于什么用途,很可能您都想要 FFT 或功率谱密度的幅度。 谢谢!我想获得每帧的峰值频率(帧长度取决于窗口长度和移位长度) 【参考方案1】:

FFT 中的第一个 bin 是 DC (0 Hz),第二个 bin 是 Fs / N,其中 Fs 是采样率,N 是 FFT 的大小。下一个 bin 是2 * Fs / N。为了笼统地表达这一点,nth bin 是n * Fs / N

因此,如果您的采样率 Fs 是 44.1 kHz 并且您的 FFT 大小 N 是 1024,那么 FFT 输出箱位于:

  0:   0 * 44100 / 1024 =     0.0 Hz
  1:   1 * 44100 / 1024 =    43.1 Hz
  2:   2 * 44100 / 1024 =    86.1 Hz
  3:   3 * 44100 / 1024 =   129.2 Hz
  4: ...
  5: ...
     ...
511: 511 * 44100 / 1024 = 22006.9 Hz

请注意,对于实数输入信号(虚部全为零)FFT 的后半部分(从 N / 2 + 1N - 1 的区间)不包含有用的附加信息(它们与第一个 N / 2 - 1 具有复共轭对称性垃圾箱)。最后一个有用的 bin(用于实际应用)位于 N / 2 - 1,对应于上例中的 22006.9 Hz。 N / 2 处的 bin 表示奈奎斯特频率下的能量,即 Fs / 2(在本例中 = 22050 Hz),但这通常没有任何实际用途,因为抗混叠滤波器通常会衰减任何高于或高于该频率的信号Fs / 2.

【讨论】:

注意——答案有点错误——第 512 个桶包含 22050 的级别,即奈奎斯特限制。包含 0 到 N/2 的 bin 包含有用的值。 感谢您的编辑和澄清...我想这就是我发现缺乏实用性的地方。我:但是,大师,FFT 的工作达到了奈奎斯特!你:学徒,你真的应该把它过滤掉。 我希望我能给答案加星标。这个答案比原来的问题还要好! @PaulR - 我想感谢您多年来为我服务的精彩回答。在我拥有 *** 帐户之前,我会访问这个答案,实际上我在注册后忘记了感谢你。我最近在看 FFT 的东西,我记得你的答案,现在才去看看。一旦我到了这里,我记得要谢谢你……所以谢谢你!每当我与某人争论解释 FFT 水平轴上的每个点是什么时,我都会将他们指向此链接。 @rayryeng:非常感谢 - 我认为这是我在 SO 上回答问题约 5 年来得到的最好的确认!【参考方案2】:

看看我的回答here。

回复评论:

FFT 实际上是在等间隔频率范围内使用正弦和余弦函数(基函数)计算输入信号的cross-correlation。对于给定的 FFT 输出,我发布的答案给出了相应的频率 (F)。输出样本的实部是输入信号与cos(2*pi*F*t) 的互相关,虚部是输入信号与sin(2*pi*F*t) 的互相关。输入信号与sincos 函数相关的原因是要考虑输入信号和基函数之间的相位差。

通过取复数 FFT 输出的幅度,您可以衡量输入信号与一组频率的正弦曲线的相关程度,而与输入信号相位无关。如果您只是分析信号的频率内容,您几乎总是会取 FFT 复数输出的幅度或幅度平方。

【讨论】:

实部和虚部是用来做FFT的结果吗?请为我解释。谢谢 会不会是复杂输出的大小都必须加倍? (如果我将我的解释限制在下半部分)【参考方案3】:

我用过以下:

public static double Index2Freq(int i, double samples, int nFFT) 
  return (double) i * (samples / nFFT / 2.);


public static int Freq2Index(double freq, double samples, int nFFT) 
  return (int) (freq / (samples / nFFT / 2.0));

输入是:

i: Bin 访问 samples:以赫兹为单位的采样率(即 8000 Hz、44100Hz 等) nFFT: FFT 向量的大小

【讨论】:

人们无法确切知道您使用samplesnFFT 代表什么。因此,请使其更具解释性。 接受的答案说这应该是i * samples / nFFT。为什么那里有多余的2?我错过了什么吗? @yatisagade 如果您的采样频率是 44100Hz,那么您实际可以获得的最高频率是一半,即 22050Hz。它被称为奈奎斯特频率(查看***了解详细信息)。人类的听觉系统无法感知 >~20kHz 的任何东西,这就是为什么 44.1kHz 是最常见的采样率。 另外,我认为在这种情况下nFFT 只涉及实际 FFT 的一半(许多函数都这样做,因为后半部分只是前半部分的镜像)【参考方案4】:

FFT 输出系数(对于大小为 N 的复数输入)从 0 到 N - 1 分组为 [LOW,MID,HI,HI,MID,LOW] 频率。

我认为 k 处的元素与 N-k 处的元素具有相同的频率,因为对于实际数据,FFT[N-k] = FFT[k] 的复共轭。

从低频到高频的扫描顺序是

0,

 1,
 N-1,

 2,
 N-2

 ...

 [N/2] - 1,
 N - ([N/2] - 1) = [N/2]+1,

 [N/2]

从索引 i = 0 到 [N/2] 有 [N/2]+1 组频率,每组具有frequency = i * SamplingFrequency / N

所以 bin FFT[k] 处的频率为:

if k <= [N/2] then k * SamplingFrequency / N
if k >= [N/2] then (N-k) * SamplingFrequency / N

【讨论】:

【参考方案5】:

你的第 kth FFT 结果的频率是 2*pi*k/N。

【讨论】:

我猜这应该是弧度

以上是关于如何获得 FFT 中每个值的频率?的主要内容,如果未能解决你的问题,请参考以下文章

如何在每个FFT计算中检索不同的原始频率并且在java中没有任何频率泄漏

如何将 FFT 应用于录音以获取频率?

FFT后如何得到幅度和对应的频率

具有负 fft 值的傅里叶变换和滤波频率

FFT 频率分析似乎得到了错误的值

使用 vDSP 的 FFT 频率范围