我试图通过使用FFTW库的函数对C 中的两个信号 和进行卷积,对每个信号执行傅里叶变换,将适当的复杂分量相乘,然后对结果乘积进行 IFFT。不幸的是,我的 IFFT 结果不正确,我不确定我做错了什么。
我正在使用我在网上找到的代码的修改版本(此处为 .c 和 Makefile )进行测试,该版本使用 0 到 1 之间的随机数填充两个数组。我的过程如下:
- 分别为长度和长度的(音频信号)和(脉冲响应)创建
double缓冲区。xhnnIR - 用 0 到 1 之间的随机数填充每个缓冲区。
- 创建两个
complex缓冲区X和H,每个缓冲区的长度nOut = n + nIR - 1 - 创建并执行两个从实数到复数的 FFT 计划,每个信号一个,都使用
nOut元素(即plan_forward = fftw_plan_dft_r2c_1d ( nOut, x, X, FFTW_ESTIMATE );和plan_forwardIR = fftw_plan_dft_r2c_1d (nOut, h, H, FFTW_ESTIMATE); - 创建复数数组
fftMulti以保存两个数组的频率乘积。它的大小是nc = nOut / 2 + 1因为 FFTW 不存储 FFT 的冗余一半 - 循环
for ( i = 0; i < nc; i++ )并执行复数乘法,即fftMulti[i][0] = X[i][0] * H[i][0] - X[i][1] * H[i][1];实部和fftMulti[i][1] = X[i][0] * H[i][1] + X[i][1] * H[i][0];虚部 - 创建大小
double数组。该数组将保存 IFFTconvolvedSignOutfftMulti - 创建并执行大小为 的复数到实数的 FFT 计划
nOut,即plan_backwardConv = fftw_plan_dft_c2r_1d(nOut, fftMulti, convolvedSig, FFTW_ESTIMATE); convolvedSig通过将每个元素除以标准化nOut
中的值convolvedSig不正确(它们太高了),但我不确定我做错了什么。我还为我未修改的信号X和H(也是大小nOut)创建了数组和复数到实数的计划,并且这些 IFFT 工作得很好(即,值与我对它们执行 FFT 之前的值完全相同)。
使用我的流程和/或我的代码,有人可以帮我确定我做错了什么吗?