1

私はFFTWをCで動作させようとしています.以前は別のプロジェクト(JNIにあった)で動作していました.悲しいことに、そのプロジェクトからコードを多かれ少なかれコピーしています.

まず、次のようにサイン信号を生成します。

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;
}    

これは機能します。完全を期すために投稿しているだけです。

次に、FFTW を使用して信号を変換します。これは、次の方法で行います ( FFTW のドキュメントに基づく)。

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);
}

FFTWのドキュメントからこれに注意してください:typedef double fftw_complex[2];

これで、-arrayのすべての値signalが -0.000000 になります。このコードの問題が本当にわからないので、私が間違っていることを指摘してもらえますか?

ありがとう。

PS: わかりやすくするために、コードから print-statement を削除しました。

4

2 に答える 2

0

問題は、前の反復の虚数部を現在の反復の実数部で上書きしていることだと思います。

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は各反復で1つずつ増分するため、最初の反復でptrは、入力複素数[0]ptr + 1の実数部を指し、複素数[0]の虚数部を指しますが、2番目の反復でptrは、虚数を指します。複素数[0]ptr + 1の一部であり、複素数[1]の実数部を指しています。

この問題を修正するためのいくつかの提案は次のとおりです。

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
}

また

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
    }
于 2012-03-03T00:24:43.630 に答える
0

おやおや、これはばかげています。

値は -2.0E-9 のような大きさです。結果は丸められるため、-0.00000 が出力されます。

フレッドに感謝します。彼の質問「期待されるアウトプットは何ですか?」前に述べたJNIプロジェクトの出力をよく見て、自分の間違いに気づきました。

また、他の回答もありがとうございます!

于 2012-03-03T11:11:50.833 に答える