2012-01-30 19 views
0

まず、私はDSPに関連するものは全く新しく、私は本当に奇妙で愚かなことを尋ねているかもしれません。周波数サンプリングフィルタの実装

注:システムは、私があまりにも新しいですので、私はリンクに、その後ほこりを投稿することができません。私はシステムのリンクとして認識しないように、リンクの前に - を追加することにしました。とにかく投稿することができます。残念ながら、これは、あなたがこのことについて申し訳ありませんリンクを、従うこと/過去をコピーする必要があります意味..

私は現在、全体の可聴音スペクトルの制御を必要とするアプリケーションを書いています。私はいくつかの情報を読んだ後に私にこの種の制御を与えることができると思ったので、周波数サンプリングフィルタを選択しました。私の実装は、44100Hzのサンプリング周波数で0-PI範囲の80個の共振器に給電するコムフィルタで構成されています。

私がまま現在以下のインパルス応答を取得しています: http://img545.imageshack.us/img545/1979/10269409.png

現在frequncy応答は次のようになります。 http://img198.imageshack.us/img198/24/freqj.png

私は、このように画像のリンクについて申し訳ありませんが、システムが勝ちました私も新しいだから「tは私に画像を投稿することができます私はすべての私のフィルター

ことを行うことを許可されていた場合、私はコメントのコードへのリンクを配置しますので、私はまた、唯一の2つのリンクを許可していますこのランでは係数は1である

私の結論は、共振器が、それぞれのピークを同じ高さにしたいと思ったところで部分的に相殺し合っていることです。 これを修正する方法を見つけることができないようですが、私を助けることができる人はいますか?

EDIT 1: 私はここで最も重要な機能を入れている、私はLOT早くことを行っているはずです。私は明確ではないかもしれないことをすべて晴らしています。

//comb filter function 
float filter::comb(buffer* x, float z, float input){ 
    //store the new input value in the buffer 
    x->write(input); 
    //calculate the output value according to Y[n] = X[n] - z * X[n-160] 
    return x->read(0)-(z*x->read(160)); 
} 

//resonator function 
float filter::resonator(buffer* res, float r, float w, float phi, float amp){ 
static int odd_even=1; 
float result=0; 

if(odd_even){ 
    odd_even=0; 
    //if called odd times calculate result according to Y[n] = 2 * r * cos(phi) * y[n-1] - r^2 * y[n-1] + amp * w 
    result=(2*r*cos(phi)*res->read(0))-(r*r*res->read(1))+(amp*w); 
} 
else{ 
    odd_even=1; 
    //if called odd times calculate result according to Y[n] = 2 * r * cos(phi) * y[n-1] - r^2 * y[n-1] - amp * w 
    result=(2*r*cos(phi)*res->read(0))-(r*r*res->read(1))-(amp*w); 
} 

//store result in buffer 
res->write(result); 

return result/SCALE; 
} 

//filter execute function 
float filter::exec(float value){ 
    float w; 
    float total=0; 
    float temp=0; 

    cout<<value<<"\t"; 
    //calculate the comb output 
    w=comb(combX,0.886867188,value); 
    for(int i=0;i<80;i++){ 
     temp=(resonator(&res[i],0.999,w,(((1.125+i*2.25)/180.0)*pi),getCoef(i))); 
     total+=temp; 
    } 
    return total; 
} 

EDIT 2:91.125度

1共振器: -http:

を//img708.imageshack.us/img708/9995/42515591.png私はこれはかなりあると思います所望の結果、所望の周波数で強い応答68.625及び113.625度で

2共振器: -http://img717.imageshack.us/img717/6840/3050.png

これは望ましい応答にも近いと思います。私はピークが1つの共振器テストでより大きくなっているのはちょっと奇妙だと思う。 21.375で、その後、10度刻みで始まる

8共振器: -http:

は、私はこの1つの何をするかわからない//img269.imageshack.us/img269/8461/8resonators.png最後の共振器は極端な応答を有するが、他の共振器は何が起こるべきかに合っているようである。

EDIT 3: -http://img810.imageshack.us/img810/8418/68001938 私は16段の共振器で別のテストをしました。png

これは、8共振器テストとほぼ同じ結果を示しています。主な相違点は、PIの近くで起こっているのと同じエフェクトが0Hz付近で見え始めていることです。

+0

C++コードはhttp://dl.dropbox.com/u/39710897/filter.rarから入手できます – Gurba

+3

これを1つの特定の質問に絞り込むには、いくつかの作業を行う必要があります。あなたのためのコードのリアルタイムデバッグ連鎖。 –

+1

私は基本的な質問はむしろ単純だと思います:私の結論(共振器同士は互いに打ち消し合っています)は意味がありますか?もしそうなら、それを修正するための私の選択肢は何ですか? – Gurba

答えて

1

問題は、共振器ゲインを正規化していないことです。通過帯域が0またはpiに近づくにつれて、2つの極が互いに接近し、通過帯域内のエネルギー注入が両方の極を励起し始めるため、それらは異なる非正規化利得を有する。

各フィルタの帯域通過ゲインを(通過帯域の中心での振幅応答をz変換を使って評価することによって)計算し、その出力をそれで除算する必要があります。クイック・バック・オブ・エンベロープ計算により、乗法的正規化係数は(1-r) * sqrt(r^2 - 2.r.cos(2.phi) + 1)になりますが、確認してください!

詳細が必要な場合はお知らせください。

+0

私は正規化を適用するには?共振器出力に正規化係数を掛けるだけでいいですか? – Gurba

+0

@ Gurba:はい、または入力。しかし、バッファに書き戻されているものを乗算しないように注意してください。 –

+0

ありがとう!、これは私に長い道のりをもたらすようです。あなたの提案は、およそ64倍もの価値をもたらしたように思えますが、私はチェック、精密検査、ダブルチェック、トリプルチェックではまだ忙しいですが、確かに今のところよく見えます。 – Gurba

0

IIRフィルタを共振器として使用している場合、線形位相ではなく、周波数応答特性のオーバーラップは、重複する周波数ポイントでの位相応答に応じてキャンセルまたは合計することができます。

しかし、Paul Rが示唆しているように、個々のフィルタを個別にテストし、次にペアでテストして、各フィルタのゲインを測定し、フィルタのクロスオーバーポイントで何が起こるかを確認する必要があります。

+0

いくつかのテストを実行しており、後で結果を投稿します(テストを実行した後) – Gurba

+0

テストを追加しました結果(およびいくつかのコード)元の質問 – Gurba