6

我一直在使用 FFT,目前正在尝试使用 FFT 从文件中获取声音波形(最终修改它),然后将修改后的波形输出回文件。我得到了声波的 FFT,然后在上面使用了逆 FFT 函数,但输出文件听起来根本不对。我没有对波形进行任何过滤——我只是在测试获取频率数据,然后将其放回文件中——听起来应该是一样的,但听起来却大不相同。

从那以后,我一直在研究这个项目,但还没有得到想要的结果。输出的声音文件很嘈杂(更大声,以及原始文件中不存在的额外噪音),并且来自一个通道的声音泄漏到另一个通道(之前是静音的)。输入声音文件是一个立体声、2 声道文件,声音仅来自一个声道。这是我的代码:

import scipy
import wave
import struct
import numpy
import pylab

from scipy.io import wavfile

rate, data = wavfile.read('./TriLeftChannel.wav')

filtereddata = numpy.fft.rfft(data, axis=0)
print(data)

filteredwrite = numpy.fft.irfft(filtereddata, axis=0)
print(filteredwrite)

wavfile.write('TestFiltered.wav', rate, filteredwrite)

我不太明白为什么这不起作用。

我已经压缩了问题 .py 文件和音频文件,如果这可以帮助解决这里的问题。

4

4 回答 4

6
  1. 您似乎没有在此处应用任何过滤器
  2. 您可能希望采用ifftfft后过滤),而不是输入波形。
于 2012-04-19T06:39:45.540 回答
4

不应该更像这样吗?

filtereddata = numpy.fft.fft(data)
# do fft stuff to filtereddata
filteredwrite = numpy.fft.ifft(filtereddata)
wavfile.write('TestFiltered.wav', rate, filteredwrite)
于 2012-04-19T06:49:55.490 回答
4
>>> import numpy as np
>>> a = np.vstack([np.ones(11), np.arange(11)])

# We have two channels along axis 0, the signals are along axis 1
>>> a
array([[  1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.],
       [  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.]])
>>> np.fft.irfft(np.fft.rfft(a, axis=1), axis=1)
array([[  1.1       ,   1.1       ,   1.1       ,   1.1       ,
          1.1       ,   1.1       ,   1.1       ,   1.1       ,
          1.1       ,   1.1       ],
       [  0.55      ,   1.01836542,   2.51904294,   3.57565618,
          4.86463721,   6.05      ,   7.23536279,   8.52434382,
          9.58095706,  11.08163458]])
# irfft returns an even number along axis=1, even though a was (2, 11)

# When a is even along axis 1, we get a back after the irfft.
>>> a = np.vstack([np.ones(10), np.arange(10)])
>>> np.fft.irfft(np.fft.rfft(a, axis=1), axis=1)
array([[  1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
          1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
          1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
          1.00000000e+00],
       [  7.10542736e-16,   1.00000000e+00,   2.00000000e+00,
          3.00000000e+00,   4.00000000e+00,   5.00000000e+00,
          6.00000000e+00,   7.00000000e+00,   8.00000000e+00,
          9.00000000e+00]])

# It seems like you signals are along axis 0, here is an example where the signals are on axis 0
>>> a = np.vstack([np.ones(10), np.arange(10)]).T
>>> a
array([[ 1.,  0.],
       [ 1.,  1.],
       [ 1.,  2.],
       [ 1.,  3.],
       [ 1.,  4.],
       [ 1.,  5.],
       [ 1.,  6.],
       [ 1.,  7.],
       [ 1.,  8.],
       [ 1.,  9.]])
>>> np.fft.irfft(np.fft.rfft(a, axis=0), axis=0)
array([[  1.00000000e+00,   7.10542736e-16],
       [  1.00000000e+00,   1.00000000e+00],
       [  1.00000000e+00,   2.00000000e+00],
       [  1.00000000e+00,   3.00000000e+00],
       [  1.00000000e+00,   4.00000000e+00],
       [  1.00000000e+00,   5.00000000e+00],
       [  1.00000000e+00,   6.00000000e+00],
       [  1.00000000e+00,   7.00000000e+00],
       [  1.00000000e+00,   8.00000000e+00],
       [  1.00000000e+00,   9.00000000e+00]])
于 2012-04-25T01:37:35.320 回答
2

两个问题。

您正在 FFTing 2 通道数据。您应该只 FFT 1 通道的单声道数据,以使 FFT 结果具有一般意义。如果要处理 2 个声道的立体声数据,则应分别对每个声道进行 IFFT(FFT())。

您正在使用真正的 fft,它会丢弃信息,从而使 fft 不可逆。

如果要反转,则需要使用产生复数结果的 FFT,然后将这个复数频域矢量 IFFT 回时域。如果您修改频域矢量,如果您想要一个严格的实数结果(减去数值噪声),请确保它保持共轭对称。

于 2012-04-19T22:50:59.007 回答