2016-09-10 12 views
0

まだ信号処理が新しく、FFTWを使ってVSTプラグインを作成したかったのですが(Rosetta Codeで見つかったFFTとIFFTも機能していたようですゆっくりと)、各入力サンプルにFFTを適用して(無用に)、その結果にIFFTを適用します。目標はオリジナルのサウンドを元に戻すことでしたが、出力は(サウンドの品質を表現するためのより良い用語の知識がないため)「文字化けしました」と思われます。ここでprocessReplacing関数のコードは次のとおりです。out4out5に戻ってほとんど同じVSTプラグインでFFTWを使った "Garbled"音

void VST_Testing::VST_Testing::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) { 
    resume(); 
    time = 0; 
    float *in1 = inputs[0]; 
    float *in2 = inputs[1]; 
    float *out1 = outputs[0]; //L 
    float *out2 = outputs[1]; //R 
    float *out3 = outputs[2]; //C 
    float *out4 = outputs[3]; //RL 
    float *out5 = outputs[4]; //RR 
    VstInt32 initialFrames = sampleFrames; 
    fftw_complex* left = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*sampleFrames); 
    fftw_complex* right = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*sampleFrames); 
    int i = 0; 
    while (--sampleFrames >= 0) 
    { 
     left[i][0] = *in1++; 
     left[i][1] = 0; 
     right[i][0] = *in2++; 
     left[i][1] = 0; 
     i++; 
    } 
    sampleFrames = initialFrames; 

    fftw_complex* l_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*sampleFrames); 
    fftw_complex* r_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*sampleFrames); 

    fftw_plan p_l = fftw_plan_dft_1d(sampleFrames, left, l_out, FFTW_FORWARD, FFTW_MEASURE); 
    fftw_plan p_r = fftw_plan_dft_1d(sampleFrames, right, r_out, FFTW_FORWARD, FFTW_MEASURE); 

    fftw_execute(p_l); 
    fftw_execute(p_r); 

    fftw_destroy_plan(p_l); 
    fftw_destroy_plan(p_r); 

    p_l = fftw_plan_dft_1d(sampleFrames, l_out, left, FFTW_BACKWARD, FFTW_MEASURE); 
    p_r = fftw_plan_dft_1d(sampleFrames, r_out, right, FFTW_BACKWARD, FFTW_MEASURE); 

    fftw_execute(p_l); 
    fftw_execute(p_r); 
    i = 0; 
    while (--sampleFrames >= 0) 
    { 
     (*out3++) = 0.5*left[i][0] + 0.5*right[i][0]; 
     (*out4++) = left[i][0]; 
     (*out5++) = right[i][0]; 
     i++; 
    } 

    fftw_destroy_plan(p_l); 
    fftw_destroy_plan(p_r); 

    fftw_free(left); 
    fftw_free(right); 
    fftw_free(l_out); 
    fftw_free(r_out); 
    } 
} 

私の期待は、私がin1in2(予想使用中の左右入力)からの信号になるだろうということでした入力(左後後ろ右出力)を使用することができます。コード内で間違いを犯したのですか、FFTWの行動が間違っていると思いますか? FFTW参照から

答えて

1

FFTW_MEASUREは、実際にいくつかのFFTを計算し、その実行時間を計測することにより、最適化計画を見つけるために、FFTWを伝えます。お使いのマシンによっては、時間がかかることがあります(しばしば数秒かかる)。

これは、このルーチンを事前に実行してから、作成した計画を使用し、サイクルごとに再作成しないことをお勧めします。もちろん、これにはフレームの固定サイズが必要ですが、とにかく遅かれ早かれこの問題に直面しました。

1

おそらくないあなただけの問題がありますが、ここでのコピー&ペーストの誤差があります

while (--sampleFrames >= 0) 
{ 
    left[i][0] = *in1++; 
    left[i][1] = 0; 
    right[i][0] = *in2++; 
    left[i][1] = 0; // <<< should be right[i][1] = 0; 
    i++; 
} 
2

問題が明らかに事実はFFTW計算し、コピー&ペーストのエラーに加えて、によって引き起こされました正規化されていない変換。 「What FFTW really computes」から

FFTWは、非正規化変換を計算します。つまり、DFTの合計の前に係数がありません。言い換えると、順方向変換と逆方向変換を適用すると、入力にnが乗算されます。

この問題に対する解決策は、正規化するために、initialFramesて信号を分割することであった。

while (--sampleFrames >= 0) 
{ 
    (*out3++) = 0.5*(left[i][0]/initialFrames) + 0.5*(right[i][0]/initialFrames); 
    (*out4++) = left[i][0]/initialFrames; 
    (*out5++) = right[i][0]/initialFrames; 
    i++; 
} 
関連する問題