Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FFTW: signal consists of noise after IFFT

Tags:

c++

c

noise

fft

fftw

After doing FFT and IFFT I can hear only noise in my headphones... Here is the code:

        double* spectrum = new double[n];

        fftw_plan plan;

        plan = fftw_plan_r2r_1d(n, data, spectrum, FFTW_REDFT10, FFTW_ESTIMATE);

        fftw_execute(plan);
        fftw_destroy_plan(plan);

        plan = fftw_plan_r2r_1d(n, spectrum, data, FFTW_REDFT01, FFTW_ESTIMATE);
        fftw_execute(plan);
        fftw_destroy_plan(plan);

Maybe I've chosen wrong FFT type?
P.S. data is the initial signal

UPDATE

Ok, so now the code is

        fftw_complex* spectrum = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);

        fftw_plan plan;

        plan = fftw_plan_dft_r2c_1d(n, data, spectrum, FFTW_ESTIMATE);

        fftw_execute(plan);
        fftw_destroy_plan(plan);

        plan = fftw_plan_dft_c2r_1d(n, spectrum, data, FFTW_ESTIMATE);
        fftw_execute(plan);
        fftw_destroy_plan(plan);

The problem remains the same, my data array is corrupted.

UPDATE #2

So, the problem is in my transform size and normalizing. If I user real-to-real FFTW_REDFT10 and FFTW_REDFT01 transforms which transform sizes i need to use? 2*n? Or something else? And then I need to normalize my output signal by dividing each element by 2*n?
Thank to all for replying.

UPDATE #3

Thanks to all for replying again. I've solved the problem with your help. Here is the working code:

        // FFT  
        fftw_complex* spectrum  = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);

        fftw_plan plan;

        plan = fftw_plan_dft_r2c_1d(n, data, spectrum, FFTW_ESTIMATE);

        fftw_execute(plan);
        fftw_destroy_plan(plan);

        // some filtering here

        // IFFT
        plan = fftw_plan_dft_c2r_1d(n, spectrum, data, FFTW_ESTIMATE);
        fftw_execute(plan);
        fftw_destroy_plan(plan);

        // normalizing

        for (int i = 0; i < n; i++) {
            data[i] = data[i] / n;
        }
like image 303
Kirill Dubovikov Avatar asked Dec 13 '10 15:12

Kirill Dubovikov


2 Answers

I don't see where you are normalizing your output. You must divide your output values by the number of elements in the data array to normalize the data back to original range of values.

See the FFTW Manual 4.8.2, last paragraph (I have V3.2 manual).

like image 186
Steve Fallows Avatar answered Oct 25 '22 16:10

Steve Fallows


You're performing a real-to-real FFT (actually, FFTW is computing a DCT, or discrete cosine transform, internally, but it results in the same thing). Be careful about the number of points that are computed in the output spectrum array. A real-to-real transform only has n/2+1 actual values placed into the array.

If, as you indicated, you compute a real-to-complex transform, you will generate both sides of the spectrum (they are complex conjugates of each other) but your output array will need to be resized to accommodate complex values plus the DC result.

like image 41
sizzzzlerz Avatar answered Oct 25 '22 16:10

sizzzzlerz