【问题标题】:Understanding FFT operations in Python code snippet了解 Python 代码片段中的 FFT 运算
【发布时间】:2012-11-17 23:04:34
【问题描述】:

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

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。

这是某种标准化吗?

这是来源:

http://www.swharden.com/blog/2010-03-05-realtime-fft-graph-of-audio-wav-file-or-microphone-input-with-python-scipy-and-wckgraph/

【问题讨论】:

    标签: python fft


    【解决方案1】:

    我不了解 Python,但它看起来只是将实数到复数 FFT 输出的两个镜像复共轭一半的幅度相加。您可以只取前半部分的大小并乘以 2。

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

    【讨论】:

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

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

    但是我不知道为什么要修建运河。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-28
      • 2019-04-16
      • 1970-01-01
      相关资源
      最近更新 更多