使用快速傅立叶变换分析音频


问题内容

我正在尝试在python中创建图形频谱分析仪。

我目前正在读取16位双通道,44,100
Hz采样率音频流的1024字节并将两个通道的幅度平均在一起。因此,现在我有一系列256条带符号的短裤。现在,我想使用numpy之类的模块在该阵列上执行fft,并使用结果创建图形频谱分析仪,其开始时只有32条。

我已经阅读了有关快速傅立叶变换和离散傅立叶变换的维基百科文章,但是我仍然不清楚结果数组代表什么。这是我使用numpy在数组上执行fft后的数组外观:

   [ -3.37260500e+05 +0.00000000e+00j   7.11787022e+05 +1.70667403e+04j
   4.10040193e+05 +3.28653370e+05j   9.90933073e+04 +1.60555003e+05j
   2.28787050e+05 +3.24141951e+05j   2.09781047e+04 +2.31063376e+05j
  -2.15941453e+05 +1.63773851e+05j  -7.07833051e+04 +1.52467334e+05j
  -1.37440802e+05 +6.28107674e+04j  -7.07536614e+03 +5.55634993e+03j
  -4.31009964e+04 -1.74891657e+05j   1.39384348e+05 +1.95956947e+04j
   1.73613033e+05 +1.16883207e+05j   1.15610357e+05 -2.62619884e+04j
  -2.05469722e+05 +1.71343186e+05j  -1.56779748e+04 +1.51258101e+05j
  -2.08639913e+05 +6.07372799e+04j  -2.90623668e+05 -2.79550838e+05j
  -1.68112214e+05 +4.47877871e+04j  -1.21289916e+03 +1.18397979e+05j
  -1.55779104e+05 +5.06852464e+04j   1.95309737e+05 +1.93876325e+04j
  -2.80400414e+05 +6.90079265e+04j   1.25892113e+04 -1.39293422e+05j
   3.10709174e+04 -1.35248953e+05j   1.31003438e+05 +1.90799303e+05j...

我想知道这些数字究竟代表什么,以及如何将这些数字转换为32个条形图的高度的百分比。另外,我应该将两个通道平均在一起吗?


问题答案:

您要显示的阵列是音频信号的傅立叶变换系数。这些系数可用于获取音频的频率内容。FFT是为复数值输入函数定义的,因此即使输入都是实数值,得出的系数也将是虚数。为了获得每个频率的功率量,您需要计算每个频率的FFT系数的大小。这
不仅 是系数的实部,还需要计算其实部和虚部的平方和的平方根。也就是说,如果您的系数为a + b * j,则其大小为sqrt(a ^ 2 + b ^
2)。

计算完每个FFT系数的幅度后,您需要确定每个FFT系数属于哪个音频。N点FFT将为您提供从0开始的N个等间隔频率的信号频率内容。因为您的采样频率为44100个样本/秒。并且FFT中的点数为256,则您的频率间隔为44100/256
= 172 Hz(大约)

数组中的第一个系数将是0频率系数。这基本上是所有频率的平均功率水平。其余系数将从0开始以172
Hz的倍数递增,直到达到128。在FFT中,您最多只能测量采样点一半的频率。如果您是惩罚的贪食者,并且需要知道为什么,请阅读奈奎斯特频率奈奎斯特-
香农采样定理
上的这些链接,但是基本结果是,您的低频将被复制或混叠在高频频段中。因此,频率将从0开始,对每个系数增加172 Hz,直到N / 2系数,然后降低172 Hz,直到N-1系数。

那应该是足够的信息来帮助您入门。如果您想对FFT进行比维基百科更平易近人的介绍,可以尝试了解数字信号处理:第二版。。这对我很有帮助。

这就是这些数字所代表的含义。可以通过将每个频率分量幅度乘以所有分量幅度的总和来转换为高度百分比。虽然,这只能代表相对频率分布,而不能代表每个频率的实际功率。您可以尝试按频率分量的最大幅度进行缩放,但我不确定该显示效果是否很好。找到可行的比例因子的最快方法是对响亮和柔和的音频信号进行实验,以找到正确的设置。

最后,如果要整体显示整个音频信号的频率内容,则应将两个通道平均在一起。您正在将立体声音频混合为单声道音频并显示组合的频率。如果您想要左右两个频率分别显示,那么您将需要在每个通道上分别执行傅立叶变换。