I'm trying to convolve two signals $x(n)$ and $h(n)$ in C by using the FFTW library's functions to perform a Fourier transform on each, multiply the appropriate complex components together, and take the IFFT of the resultant product. Unfortunately, my IFFT'd result isn't correct, and I'm not sure what I'm doing incorrectly.
I'm testing using a modified version of code I found online (.c and Makefile here), which populates two arrays with random numbers between 0 and 1. My process is as follows:
- Create
double
buffers forx
(audio signal) andh
(impulse response) of lengthsn
andnIR
respectively. - Populate each buffer with random numbers between 0 and 1.
- Create two
complex
buffersX
andH
, each of lengthnOut = n + nIR - 1
- Create and then execute two real-to-complex FFT plans, one for each of the signals, both using
nOut
elements (i.e.plan_forward = fftw_plan_dft_r2c_1d ( nOut, x, X, FFTW_ESTIMATE );
andplan_forwardIR = fftw_plan_dft_r2c_1d (nOut, h, H, FFTW_ESTIMATE);
- Create complex array
fftMulti
to hold the frequency products of the two arrays. Its size isnc = nOut / 2 + 1
because FFTW doesn't store the redundant half of the FFT - Loop
for ( i = 0; i < nc; i++ )
and perform complex multiplication, i.e.fftMulti[i][0] = X[i][0] * H[i][0] - X[i][1] * H[i][1];
for the real component andfftMulti[i][1] = X[i][0] * H[i][1] + X[i][1] * H[i][0];
for the imaginary component - Create
double
arrayconvolvedSig
of sizenOut
. This array will hold the IFFT offftMulti
- Create and execute a complex-to-real FFT plan of size
nOut
, i.e.plan_backwardConv = fftw_plan_dft_c2r_1d(nOut, fftMulti, convolvedSig, FFTW_ESTIMATE);
- Normalize
convolvedSig
by dividing each element bynOut
The values in convolvedSig
are not correct (they are way too high), but I'm not sure what I'm doing wrong. I also created arrays and complex-to-real plans for my unmodified signals X
and H
(also of size nOut
), and those IFFTs worked just fine (i.e. values were exactly the same as before I performed FFTs on them).
Using my process and/or my code, can someone please help me identify what I'm doing incorrectly?