Pregunta

I'm trying to get FFTW to work in C. It used to work for another project (which was in JNI), and I'm more or less copying the code from that one, sadly without results.

First I generate a sine signal, like this:

double* generateSignal() {
    int fs=44100;
    double fsd = 44100.0; // fs in double format
    double f1=1000.0;
    int i;
    double PI = 3.141592653589793238462643;

    double t[fs];
    double value = 0.0;
    for (i = 0; i < fs; i++) {
        t[i] = value;
        value += 1.0/fsd;
    }

    double* signal = (double*) malloc(sizeof(double) * fs);
    for (i = 0; i < fs; i++) {
        signal[i] = sqrt(2) * sin(2 * PI * f1 * t[i]);
    }

    return signal;
}    

This works, I'm only posting it for completeness.

Next, I want to transform the signal using FFTW, which I do in the following method (based on the FFTW documentation):

void processSignal(double* signal) {
    int size = 44100;
    int i;

    fftw_complex* in = fftw_malloc(sizeof(fftw_complex) * size);
    fftw_complex* out = fftw_malloc(sizeof(fftw_complex) * size);

    for (i = 0; i < size; i++) {
        double* ptr = in[i];
        *ptr = signal[i];       // set first double, real part
        *(ptr + 1) = 0.0;       // set second double, imaginary part
    }

    fftw_plan p = fftw_plan_dft_1d(size, in, out, FFTW_FORWARD, FFTW_ESTIMATE); 
    fftw_execute(p);

    for (i = 0; i < size; i++) {
        double* ptr = out[i];
        signal[i] = *ptr;       // get real part
    }

    fftw_destroy_plan(p);
    fftw_free(in);
    fftw_free(out);
}

Please note this from the FFTW documentation: typedef double fftw_complex[2];

Now, this results in all values of the signal-array being -0.000000. I really can't see the problem with this code, so could any please point out what I'm doing wrong?

Thanks.

PS: Dropped the print-statements from my code for clarity.

¿Fue útil?

Solución 2

Gosh, this is stupid.

The values have magnitudes like -2.0E-9. The results are rounded, thus -0.00000 is printed.

A big thanks to Fred. His question "What is your expected output?" made me have a good look at the output of the JNI-project I mentioned before, and realizing my mistake.

Also thanks for the other answers!

Otros consejos

I think the problem could be that you're overwriting the imaginary part of the previous iteration with the real part of the current one.

for (i = 0; i < size; i++) {
        double* ptr = in[i];    //  <-- here's a problem
        *ptr = signal[i];       // set first double, real part
        *(ptr + 1) = 0.0;       // set second double, imaginary part
    }

i is incrementing one by one on each iteration, so on first iteration, ptr points to the real part of input complex number[0] and ptr + 1 is pointing to the imaginary part of complex number[0], but on second iteration, ptr is pointing to the imaginary part of complex number[0] and ptr + 1 is pointing to the real part of complex number[1].

Some suggestions to fix this issue could be:

for (i = 0, j = 0; i < size; i++, j+= 2) {
    double* ptr = in[j];    // j increments by 2 making ptr alays point to real part 
    *ptr = signal[i];       // set first double, real part
    *(ptr + 1) = 0.0;       // set second double, imaginary part
}

or

double* ptr = in[0]
for (i = 0; i < size; i++) {
        *ptr++ = signal[i]; // set first double, real part
        *ptr++ = 0.0;       // set second double, imaginary part
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top