FFT处理后IFFT处理后的信号不一样

Signal after processing with FFT and then IFFT is not the same

我想做一个虚拟场景的声音模拟。因此,我想以频率相关的方式将我的系统计算的脉冲响应与来自简单 .wav 文件的输入信号进行卷积。据我了解 DSP,最好的方法是使用 FFT 将输入信号转换为其频谱,以某种方式对其应用脉冲响应函数,然后将其返回 iFFT。

我的问题是,在对信号进行 FFT 和 iFFT 之后,信号与原始输入信号不同。原始声音在新信号中有点可识别,但由于 FFT 和 iFFT 后的错误数字,它非常 "blurred"。我从 http://rosettacode.org/wiki/Fast_Fourier_transform#C.2B.2B.

中获取了 C++ 中 FFT 的 "first"(就地、广度优先、频率抽取)实现示例

下面是我的FFT实现的内码用法:

CArray signal = CArray(output_size);
for (int i = 0; i < format.FrameCount; ++i) {
   signal[i] = Complex((double)(is_8_bit ? sample_data_8[i] : sample_data_16[i]), 0);
}

fft(signal);
ifft(signal);

存在以下 typedef

typedef std::complex<double> Complex;
typedef std::valarray<Complex> CArray;

由于我从上面的网站上拿了代码,所以我认为错误不可能在FFT的实现范围内。我假设它必须与我输入的数据类型 and/or 复数有关。

因为我的系统没有实现 "phases" 并且我读到它们可以被忽略并且仍然可以返回一个有用的值,所以我用 0 的虚部初始化复数。

我是否犯了一个根本错误,或者是数据类型或舍入等不应该出现的错误?

要获得正确的结果,您需要 2^n 个样本。如果您的样本少于 2^n,只需在信号末尾添加零即可。例如信号 (1,0,1,1,1) 将是 (1,0,1,1,1,0,0,0).

请测试这是否不仅仅是缩放错误。在许多情况下(但不是全部),FFT 和 iFFT 的实现没有除以样本数,因此对于长度为 N 的信号,仅

iFFT(FFT(signal))/N

returns原signal.


对于严肃的转型工作,请查看零填充和窗口化。