了解Python代码片段中的FFT操作

了解Python代码片段中的FFT操作,python,fft,Python,Fft,我在一个对音频数据进行实时FFT图形的程序中遇到了这段代码: data=scipy.array(struct.unpack("%dB"%(bufferSize*2),data)) ffty=scipy.fftpack.fft(data) ffty=abs(ffty[0:len(ffty)/2])/1000 ffty1=ffty[:len(ffty)/2] ffty2=ffty[len(ffty)/2::]+2 ffty2=ffty2[::-1]

我在一个对音频数据进行实时FFT图形的程序中遇到了这段代码:

data=scipy.array(struct.unpack("%dB"%(bufferSize*2),data))
ffty=scipy.fftpack.fft(data)
ffty=abs(ffty[0:len(ffty)/2])/1000
ffty1=ffty[:len(ffty)/2]
ffty2=ffty[len(ffty)/2::]+2                
ffty2=ffty2[::-1]                
ffty=ffty1+ffty2                              
ffty=scipy.log(ffty)-2
abs()
之后,我不理解零件背后的数学。它的作用类似于将震级数组的前半部分与后半部分相加,再加上2

这是某种正常化吗

这是来源:


我猜音频是以立体声文件格式出现的,这是左/右声道的平均值。我这么说是因为这行:
fftx=fftx[0:len(fftx)/4]
这是使用立体声信号时的常见操作


但是我不知道为什么会有一条通道被抬高。

我不知道Python,但它看起来只是将实数到复数FFT输出的两个镜像复共轭部分的大小相加。你可以很容易地只取上半部分的大小乘以2


最后,它计算对数幅值,大概是为了得到(缩放)dB值。

好吧,日志可以得到缩放后的dB幅值,但是由于dB值是任意的,没有某种0 dB的参考,我想-2只是为了得到绘图/显示所需的范围。它在
abs
表达式中获取非负频率,但它有一个一次性的错误。非负频率部分的长度需要为N//2+1。我想它会切断最后一个样本,以便为下一个部分提供一个均匀的长度向量。出于某种原因,我不知道为什么,它会在表达式的上半部分添加两个(从pi/2弧度/采样开始),将其反转并添加到频谱的下半部分。此外,不能简单地将所有非负频率分量加倍。这将使0和pi弧度/采样的值加倍,这两个值已经处于正确的值(即,它们没有拆分为共轭)。此外,只有当N为偶数时,π弧度/样本处的分量才会出现。我忽略了
解包
,这更令人困惑,但在某种程度上解释了光谱折叠。他将
int16
值解包为无符号字节('B'),将向量长度加倍。他根本不应该用NumPy/SciPy使用
struct.unpack
。但如果他这样做了,则需要将其解包为
签名的short
(格式“h”)。相反,请使用
np.frombuffer(data,dtype=np.int16)
让NumPy直接使用数据缓冲区,而不是复制内存中的数组。@eryksun-谢谢,我实际上是在代码中使用带“%dh”的struct.unpack-不明白上面为什么使用“%dB”。我想这可以解释上面的一些操作。我将切换到frombuffer()。