FFT 后频率分析中的分箱说明

信息处理 fft 声音的 数字的 奈奎斯特
2022-02-24 22:05:55

我正在创建一个 Android 应用程序,它t以 44.1kHz 的采样率记录声音几秒钟,缓冲区大小为 8192(16 位单声道样本)。我需要绘制幅度与频率的关系图,因此首先我需要在每次缓冲区满时对缓冲区运行 FFT(每秒发生多次,随着采样率的增加更是如此)。但是,在我运行 FFT 之后,我知道我需要对频率进行“bin”,然后对每个 bin 应用 A 加权。根据奈奎斯特准则,我知道我只需要查看前半个频率,而忽略对应于直流分量的第一个。但是,我不确定“装箱”的实际含义,并希望澄清它是什么,以及如何选择装在什么箱里的东西。

请指教 :) 。

3个回答

在其最简单的形式中,“分箱”过程包括将相邻 FFT 值组内的能量(平方幅度)相加。这将为您提供一组不相交的频带中的总能量。

更复杂的形式包括使用重叠的三角形滤波器组 - 您计算一系列 FFT 箱中的能量的加权和以获得一个数字,该数字可以解释为在给定的带通滤波器的输出处测量的能量中心频率/宽度。例如,可以使用这种技术来构建在频率轴上使用 1/3 倍频程刻度的可视化。

如果您希望在频率轴上绘制除 4096 个点(FFT 长度的一半)以外的图形,则必须重新采样 FFT 结果。根据您所需的 x 轴绘图分辨率,此重新分箱可能必须将多个 FFT 幅度箱合成到每个绘图点箱中。

如果您只需要绘制 FFT 频谱(即绘制幅度与频率),那么只需获取一个具有离散 FFT bin 频率的数组并将其绘制为幅度。频率仅存在于由下式给出的离散位置

f=nfsNfs2where n =0,1,2,...N

幅度 A 由下式给出

A=Magnitude(Data[n])where n =0,1,2,...N

例如,如果您有一个 8192 长的音频信号,您将执行类似于我在下面编写的小脏伪代码/C# 代码示例中所做的事情。

N = 8192;
Sample_Rate = 44100;
float[] myAudio = new Float[N];
myAudio = getAudio();
Complex[] myFFT_Audio = FFT(myAudio);  //Returns N complex values

//Get Array of frequency Values
float[] frequencies = new float[N]
for( i = 0 ; i < N; i++)
   { frequencies[i] = i * (Sample_Rate / N) - (Sample_Rate / 2); }

//Get Amplitudes
float[] Amplitudes = new float[N]
for( i = 0; i < N; i++)
  { Amplitudes[i] = myFFT_Audio[i].Magnitude(); }

//Plot Frequencies vs Amplitudes - will plot for frequencies -fs/2 to fs/2
PLOT(frequencies , Amplitudes);

如果您只想绘制来自0fs/2而不是从fs/2fs/2您可以丢弃前半部分的值,只绘制后半部分。

您还需要确保知道您的 FFT 算法返回的数据 FFT 样本类型,因为算法可以返回与任一频率相对应的 FFT 样本,范围从fs/2fs/2或从0fs. 上面的代码示例假设前者是正确的,但情况并非总是如此。

例如,Matlab 通常会给出与频率范围相对应的 FFT 样本0fs所以在这种情况下你的频率就是

f=nfsN

你仍然可以从fs/2fs/2不过很容易,因为傅里叶变换是周期性的,周期等于fs.