Forum: Mikrocontroller und Digitale Elektronik Kalkulation von BiQuads, Werte stimmen nicht.


von Borsty B. (mantabernd)


Angehängte Dateien:

Lesenswert?

Guten Tag,

ich habe mir diesen Code nach C# portiert und bekomme leider falsche 
Ergebnisse für die Biquad Coeffizienten.

http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/

Mein C# Programm liegt im Anhang.

Erstelle ich einen Peak Filter mit folgenden Eigenschaften ...

Sampling Freq:  48.000Hz
Corner Freq:    200Hz
Q:              1
Gain:           -3

... erhalte ich diese Werte:
1
a0      0,889160572865746
2
a1      -0,620483385591525
3
a2      0,351806198317308
4
b1      -0,620483385591525
5
b2      0,240966771183054
Gebe ich das Selbe hier online 
(http://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/) ein 
erhalte ich andere Werte.


Wieder andere Werte erhalte ich wenn ich meinen identischen Filter mit 
dem Analog Devices SigmaStudio generiere (siehe auch Screenshot)
1
B0_VALUE            0.00914776714314553
2
B1_VALUE            0
3
B2_VALUE            -0.00914776714314553
4
A1_VALUE            1.97348037666768
5
A2_VALUE            -0.974156870921681

Somit drei völlig unterschiedliche Werte ... wer kann hier helfen?

Meine eigene Berechnungsroutine sieht so aus:
(für diejeingen die kein Visual Studio haben...)
1
            double norm;
2
            double V = Math.Pow(10, Math.Abs(peakGain) / 20.0);
3
            double K = Math.Tan(Math.PI * Fc);
4
5
6
               if (peakGain >= 0) {    // boost
7
                    norm = 1 / (1 + 1/Q* K + K* K);
8
                    a0 = (1 + V/Q* K + K* K) * norm;
9
                    a1 = 2 * (K* K - 1) * norm;
10
                    a2 = (1 - V/Q* K + K* K) * norm;
11
                    b1 = a1;
12
                    b2 = (1 - 1/Q* K + K* K) * norm;
13
                }
14
                else {    // cut
15
                    norm = 1 / (1 + V/Q* K + K* K);
16
                    a0 = (1 + 1/Q* K + K* K) * norm;
17
                    a1 = 2 * (K* K - 1) * norm;
18
                    a2 = (1 - 1/Q* K + K* K) * norm;
19
                       b1 = a1;
20
                    b2 = (1 - V/Q* K + K* K) * norm;
21
                }


Danke!!!
Gruß Bernhard

von hsc (Gast)


Lesenswert?

Hi,

bei Sigmastudio muss man mit den Vorzeichen des Nenners aufpassen. a0 
ist fest 1, a1 und a2 werden mit -1 multipliziert, weil sich das aus der 
Struktur den Biquads ergibt. Was Du als Peaking im Netz berechnen lässt, 
ist nicht der Peaking in Sigmastudio. Dort ist das ein parametrischer 
EQ.
Zwischen den Quellen sind Zähler- und Nennenbezeichner vertauscht. Die 
Übertragungsfunktion von Sigmastudio ist H(z)=(b0 + b1*z^-1 + 
b2*z^-2)/(1 - a1*z^-1 - a2*z^-2). Die aus dem Web ist H(z)=(a0 + a1*z^-1 
+ a2*z^-2)/(1 + b1*z^-1 + b2*z^-2).

von Borsty B. (mantabernd)


Lesenswert?

Danke hsc das ist natürlich eine entscheidende Information!

Aber es bleibt die Frage warum sich meine Berechnung von denen im Netz 
unterscheiden...?

von hsc (Gast)


Angehängte Dateien:

Lesenswert?

Das sind die drei Übertrgaungsfunktionen dieser Koeffizienten
blau aus dem C#
gelb aus dem Web
rot SigmaStudio

von Borsty B. (mantabernd)


Lesenswert?

Oh mann ok ich hab den Fehler gefunden an Kopf lang

Ich habe meine Funktion so aufgerufen:
1
BiquadCalc meinBiquad = new BiquadCalc(type.bq_type_peak, 200/48.000, 1, -3.0);

Richtig muss aber natürlich so:
1
BiquadCalc meinBiquad = new BiquadCalc(type.bq_type_peak, 200.0/48000, 1.0, -3.0);

Für mich war das das Selbe aber für den PC ist das natürlich ein 
gewaltiger Unterschied :D

Jetzt schau ich mir noch das Problem mit SigmaStudio an und dann sollt 
alles passen. Danke !!!!

von hsc (Gast)


Angehängte Dateien:

Lesenswert?

Wenn ich das in Sigmastudio einstelle, kommt das raus, was die Seite 
berechnet.

von Lackl (Gast)


Lesenswert?

Borsty B. schrieb:
> Für mich war das das Selbe

Wie, 48 und 48000? Das ist aber nicht nur für den Computer ein 
Unterschied ...

von Borsty B. (mantabernd)


Angehängte Dateien:

Lesenswert?

Ich verstehe die Ausgabe von Sigma Studio leider nicht so ganz...

Einstellung siehe Screenshot, ergibt folgendes Ergebnis:
1
/* Module Gen Filter1 - General (2nd order)*/
2
#define MOD_GENFILTER1_COUNT                           5
3
#define MOD_GENFILTER1_DEVICE                          "IC1"
4
#define MOD_GENFILTER1_ALG0_STAGE0_B0_ADDR             0
5
#define MOD_GENFILTER1_ALG0_STAGE0_B0_FIXPT            0x005A3630
6
#define MOD_GENFILTER1_ALG0_STAGE0_B0_VALUE            SIGMASTUDIOTYPE_FIXPOINT_CONVERT(0.704778779309201)
7
#define MOD_GENFILTER1_ALG0_STAGE0_B0_TYPE             SIGMASTUDIOTYPE_FIXPOINT
8
#define MOD_GENFILTER1_ALG0_STAGE0_B1_ADDR             1
9
#define MOD_GENFILTER1_ALG0_STAGE0_B1_FIXPT            0xFF4D9A63
10
#define MOD_GENFILTER1_ALG0_STAGE0_B1_VALUE            SIGMASTUDIOTYPE_FIXPOINT_CONVERT(-1.39372602114209)
11
#define MOD_GENFILTER1_ALG0_STAGE0_B1_TYPE             SIGMASTUDIOTYPE_FIXPOINT
12
#define MOD_GENFILTER1_ALG0_STAGE0_B2_ADDR             2
13
#define MOD_GENFILTER1_ALG0_STAGE0_B2_FIXPT            0x00583F14
14
#define MOD_GENFILTER1_ALG0_STAGE0_B2_VALUE            SIGMASTUDIOTYPE_FIXPOINT_CONVERT(0.689425000647269)
15
#define MOD_GENFILTER1_ALG0_STAGE0_B2_TYPE             SIGMASTUDIOTYPE_FIXPOINT
16
#define MOD_GENFILTER1_ALG0_STAGE0_A0_ADDR             3
17
#define MOD_GENFILTER1_ALG0_STAGE0_A0_FIXPT            0x00FBFE0B
18
#define MOD_GENFILTER1_ALG0_STAGE0_A0_VALUE            SIGMASTUDIOTYPE_FIXPOINT_CONVERT(1.9686903317809)
19
#define MOD_GENFILTER1_ALG0_STAGE0_A0_TYPE             SIGMASTUDIOTYPE_FIXPOINT
20
#define MOD_GENFILTER1_ALG0_STAGE0_A1_ADDR             4
21
#define MOD_GENFILTER1_ALG0_STAGE0_A1_FIXPT            0xFF83EBD8
22
#define MOD_GENFILTER1_ALG0_STAGE0_A1_VALUE            SIGMASTUDIOTYPE_FIXPOINT_CONVERT(-0.969365184043474)
23
#define MOD_GENFILTER1_ALG0_STAGE0_A1_TYPE             SIGMASTUDIOTYPE_FIXPOINT

Das Web (und nun auch mein C#) bringen folgendes:
1
a0 = 0.9946985264467367
2
a1 = -1.963022368673761
3
a2 = 0.9689967515544112
4
b1 = -1.963022368673761
5
b2 = 0.963695278001148

Selbst wenn ich jetzt a1/a2 *-1 nehme komm ich nicht auf das passende 
Ergebnis :(

von hsc (Gast)


Lesenswert?

Q ~ 0,84 damit Q'=0,707. dann kommt das richtige raus.

von Borsty B. (mantabernd)


Angehängte Dateien:

Lesenswert?

hsc schrieb:
> Q ~ 0,84 damit Q'=0,707. dann kommt das richtige raus.

Tatsächlich du hast Recht wenn man den Gain von -3 auf 0 stellt...

Dann muss man aber A1/A2 noch mit *-1 multiplizieren (wie du schon 
sagtest) und aus A0 wird B0.

Hab mein Programm etwas angepasst (siehe Screenshot).

Das ist ja verrückt...


Ohne dich wäre ich da glaube ich nie drauf gekommen oO


Darf ich das einfach so hinnehmen oder gibt es dazu auch eine einfache 
Erklärung?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.