バイクアッドフィルターの振幅応答のプロット


7

バイクワッドフィルターを使用してマルチバンドオーディオEQを作成しました。RBJクックブックのメソッドを使用して係数を取得しています。

次に、振幅応答を示す曲線をプロットします。このソースからの方程式を使用しています

これは、係数を取得し、関心のあるポイントでの振幅応答を取得するための関数です。

void GetCoefficients (double samplerate = 44100.0) {

    //from the rbj biquad coefficient cookbook by Robert Bristow-Johnson
    long double SR = (long double)samplerate;
    long double A = powl(10.0L, dBGain/40.0L);
    long double W0 = 2.0L * PI * Center / SR;
    long double alpha = sinl(W0)*sinhl( LN2/2.0L * WidthInOctaves * W0/sinl(W0));

    if (Type == "peaking") {
        b0 = 1.0L + alpha * A;
        b1 = -2.0L * cosl(W0);
        b2 = 1.0L - alpha * A;
        a0 = 1.0L + alpha / A;
        a1 = -2.0L * cosl(W0);
        a2 = 1.0L - alpha / A;
    }

    long double w;
    long double numerator;
    long double denominator;
    long double magnitude;

    for (int i = 0; i < 59; ++ i) {
        w = 2.0L*PI*FreqPoints[i] / SR;  
        numerator = b0*b0 + b1*b1 + b2*b2 + 2.0L*(b0*b1 + b1*b2)*cosl(w) + 2.0L*b0*b2*cosl(2.0L*w);
        denominator = 1.0L + a1*a1 + a2*a2 + 2.0L*(a1 + a1*a2)*cosl(w) + 2.0L*a2*cosl(2.0L*w);
        magnitude = sqrtl(numerator / denominator);
        FrequencyResponse[i] = magnitude;   
    }
}

フィルターは正しく聞こえますが、プロットの継ぎ目はかなり間違っています。たとえば、幅のあるピーキングフィルターの係数を計算した場合2 オクターブ、中心 4398 Hz3 dB利得; これらの係数を使用した振幅応答349 Hz についてです 12

私は何か間違ったことをしているに違いありませんが、それを完全に理解することはできません。


1
それは私には正しいようです。明らかに問題はありません。デバッグのヒント:オールパスフィルターを試します。分子と分母が同じになるように出力され、aとbが反転します。つまり、b2 = a0、b1 = a1、b0 = a2
Hilmar

1
完全でコンパイル可能な例を示した方がよいでしょう。たとえば、FreqPoints配列またはPI定数の初期化で問題が発生する可能性があります。
Jason R

回答:


4

KRVフォーラムの誰かが、a0 = 1になるように係数を正規化する必要があると指摘しました。

b0 /= a0;
b1 /= a0;
b2 /= a0;
a1 /= a0;
a2 /= a0;
a0 = 1;

私の問題を解決しました。


ちょっとこの答えを見てください。これは、単精度の浮動小数点を使用することに悩んでいる場合に、マグニチュード応答をプロットする数値的に優れた方法を示しています。
robert bristow-johnson、2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.