2016-06-29 16 views
1

整数値を持つ配列を周波数領域にフーリエ変換する必要があります(後で別のものに乗算するため)。出力配列のサイズは44100でなければなりませんが、入力配列は変化します。C++:fftw3を使って配列を別のサイズの配列にフーリエ変換する方法

私はfftw3がそのための良いツールだと思います。しかし、どのように私は入力と出力のための異なる配列サイズの '計画'を作成するのですか?ここ

私が書いた関数である:

fftw_complex* fourier(int* samples, int numberOfSamples){ 

    fftw_complex* input; 
    fftw_complex* output; 
    fftw_plan plan; 
    input = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*numberOfSamples); 
    output = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*44100);     //cd-quality 

    plan = fftw_plan_dft_1d(44100, input, output, FFTW_FORWARD, FFTW_ESTIMATE); 
    // here is the problem because ^this 
    // array has a different size than 
    //          ^this array 

    for(size_t index = 0; index < numberOfSamples; index++){ 
     input[index][0] = (double)(samples[index]); 
     input[index][1] = 0; 
    } 
    fftw_execute(plan); 
    fftw_destroy_plan(plan); 
    fftw_free(input); 
    return output; 
} 

おかげで、離散フーリエ変換を

+2

「44100」は、オーディオサンプリングレートのように見えます。通常、 'fft'配列のサイズはサンプリングレートとは無関係であり、2の累乗です。通常、入力と出力の配列のサイズは、数学的な要件のために一致します。実際の入力データのサイズが配列のサイズと一致しない場合、これを修正するためにウィンドウ処理とゼロパディングの技法があります。この問題については十分な数の文献があります。 – user3078414

+1

他の人はすでに、入力と出力の長さが一致しなければならないと述べています。多分あなたはあなたがしようとしていることについてもう少しコンテキストを与えることができます。そのマジックナンバーに基づいて、あなたはHz(おそらく)あたり1ビンでパワースペクトルを推定しようとしているようです。その場合、44100サンプルまで入力をゼロにするだけで、スペクトルを滑らかにしなければならない入力ブロックにウィンドウ関数(ハニングを試してみる)を適用するだけです。 –

答えて

3

に答えるためにたくさんはいつもの基本的な数学的な前提として、その入力と同じサイズで出力を生成します。このアルゴリズムは、1つのサイズパラメータを取るだけでFFTWに反映されます。これは、時間領域におけるN個の離散値の配列の場合、単位時間当たり0からN-1サイクルまでの正確なN個の可能な固有周波数が存在するからである(この単位は入力の時間長である)。

基本的に入力を伸ばし、その値を補間して必要な長さに合う新しい配列を作成し、フーリエ変換を実行することで、入力のサイズを44100値に拡大または縮小できます。私は、望ましくないアーチファクトを避けるために、周波数領域ではなく入力時間領域でこのストレッチを実行することをお勧めします。

+1

線形補間はあなたができる最良のものですか?私は、あなたがサンプルを取って、信号を最も近似したsinusodialsの合計を作り、それを補間するのに使ったとしますか?これは周波数領域での比較的単純な変換に相当し、より良い方法かもしれません。 – Yakk

+0

@ Yakkはn * log(n)時間ではなく、同じことを達成しませんか? –

+2

入力をストレッチするだけでは、明らかなアーチファクトが発生することはありません。もしあなたが実際に補間する必要があるのであれば(ここでは何もしませんが、それはビンの意味を完全に変更するためです)、ナイキストの制限されたパルス形状に対して行うべきです。パフォーマンスを気にしているなら、安価な(シングルタップ)ので、周波数領域でこれを行う必要があります。周波数領域のアーティファクトが本当に心配している場合は、循環コンボルーションを通常のコンボリュージョンに変えてオーバーラップ&セーブメソッドと同じにしてください。 –

関連する問題