Zeichnen der Größenantwort eines Biquad-Filters


7

Ich habe einen Multiband-Audio-EQ mit Biquad-Filtern zusammengestellt. Ich erhalte die Koeffizienten mit den Methoden aus dem RBJ-Kochbuch .

Jetzt möchte ich die Kurve zeichnen, die die Größenantwort zeigt. Ich verwende eine Gleichung aus dieser Quelle

Hier ist meine Funktion, um die Koeffizienten und die Größenantwort an interessierenden Punkten zu erhalten.

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

Meine Filter klingen korrekt, aber meine Handlung scheint falsch zu sein. Wenn ich zum Beispiel die Koeffizienten für ein Peaking-Filter mit einer Breite von Oktaven berechnet habe , zentriert bei , mit Verstärkung; Meine Größenantwort unter Verwendung dieser Koeffizienten bei beträgt ungefähr . 24398 Hz3 dB349 Hz12

Ich muss etwas falsch machen, aber ich kann es nicht ganz herausfinden.


1
Das sieht für mich richtig aus. Es ist offensichtlich nichts falsch. Debug-Hinweis: Versuchen Sie, einen Allpass-Filter zu verwenden. Zähler und Nenner sollten gleich sein und die A & Bs sollten gekippt werden, dh b2 = a0, b1 = a1, b0 = a2
Hilmar

1
Am besten zeigen Sie ein vollständiges, kompilierbares Beispiel. Möglicherweise haben Sie beispielsweise Probleme beim Initialisieren des FreqPointsArrays oder der PIKonstante.
Jason R

Antworten:


4

Jemand vom KRV-Forum hat darauf hingewiesen, dass ich meine Koeffizienten so normalisieren muss, dass a0 = 1 ist.

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

Mein Problem gelöst.


Hey, sieh dir diese Antwort an . Es zeigt eine numerisch bessere Möglichkeit, die Größenantwort zu zeichnen, wenn Sie keine Floats mit einfacher Genauigkeit verwenden.
Robert Bristow-Johnson
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.