Koeffizientenproblem für IIR-Filter-Implemenation

OP #828234
Lesenswert?

Hallo.
Ich habe, wie man im Anhang sieht eine vorgegebene 
IIR-Filter-Implementation eines DAC-Wandlers.

Die Koeffizienten müssen als FixedPoint (Q15) vorliegen.
Mein Plan ist es 2 Shelf-Filter zu implementieren. Einen für Höhen.. 
einen für Bässe und dafür jeweils ein biquad zu verwenden.


Für einen lowShelf-Filter für die Bässe erhält man z.B. folgende 
koeffizienten:

Berechnung:

float dbGain = 20;
float A = pow(10, dbGain /40);
float omega = 2  pi   f0 / SAMP_FREQ;
float sn = sin(omega);
float cs = cos(omega);
float  beta = sqrt(A + A);
b0 = A*  ((A+1) - (A-1)*cs  + beta*sn);
b1 = 2*A*((A-1) - (A+1)*cs);
b2 = A*  ((A+1) - (A-1)*cs  - beta*sn);
a0 =     ((A+1) + (A-1)*cs) + beta*sn;
a1 = -2* ((A-1) + (A+1)*cs);
a2 =     ((A+1) + (A-1)*cs) - beta*sn;

Koeffizenten: (durch a0 dividiert)
a0 = 1
a1 = -1,98912252587406
a2 = 0,989181317356648
b0 = 1,01182878630458
b1 = -1,98885781422416
b2 = 0,977617242701964


So. Wenn man sich jetzt z.B. a1 oder b1 ansieht, sieht man, dass diese 
nicht in das Q15-Fixkomma-Format passen. (nicht in [1..-1]).
Es läge nun auf der Hand die Koeffizienten einfach durch 2.0 zu teilen.
-> Laut implementation MUSS a0 aber 1.0 (32768) sein. (wäre dann ja 0.5)

Wie geht man hier nun vor, um den gewünschen filtereffekt doch noch zu 
erhalten?
Oder mache ich etwas bei der Berechnung falsch?

Implementiere ich den Filter in Software (mit variablen a0) klingt der 
Filter wie gewünscht. Dividiere ich die Koeffizenten und setze a0 danach 
wieder auf 1.0, kommt wie erwartet humbug raus.

Was tut man in so einem Fall? Eigentlich muss a0 der größe Koeffizient 
sein um einen Filter so implementieren/betreiben zu können.

Oder kann sich der Effekt eines "a0 != 1.0" durch das 2. Biquad wieder 
ausgleichen lassen?  Das sehe ich als einzige Möglichkeit.. funktioniert 
das??

Was tun?

MFG
Angehängte Dateien:
OP #828789
Lesenswert?

So funktioniert das im SoftwareFilter zumindest, stimmt - schon 
probiert.
Ich dividiere das Ergebnis im nachhinein einfach mit dem eigentlichen 
a0. (also ~0.5 == *2)

Problem: in der festen implementation geht das nicht. Ich hab ja auch 
den AudoPfad keinen Zugriff mehr sondern nur die Filterkoeffizienten, an 
den ich was drehen kann. Ginge die Multiplikation in den 2. Biquad zu 
verschieben? Oder ist das nur eine Traumvorstellung?
Gast #828805
Lesenswert?

hallo albi,

ich kenn das von den ti-dsps (tas3103 usw) das die koeffizienten immer 
durch einen festen wert (2'er potenz) geteilt werden.
beim tas3103 wird immer durch 32 geteilt (also 2^5).
dieses "format" wird dann 5.23 genannt (5 vorkomma"stellen", 23 
nachkomma"stellen").
solange du das für ALLE koeffizienten machst, geht das auf jedem system. 
du kannst die koeffizienten auf einem tas3101 (5.23-format) sowie auf 
einem tas3004 (4.16-format) laufen lassen. mußt halt nur anders shiften.
Gast #828808
Lesenswert?

nachtrag :

bei meinem audio-projekt benutze ich das 8.24 format (also 8 bit 
vorkomma und 24 bit nachkomma). mein audio-signal hat 24 bit + 8 bit 
overhead (intern). so rechne ich durchgängig mit 32 bit zahlen. ich muß 
nur am ende einmal um 8 bit nach rechts schieben wegen dem overhead, der 
im i2s signal ja nicht vorhanden ist. da clippe ich dann einfach.
OP #828875
Lesenswert?

Ich nutzen als DAC einen "tlv320aic3101"
Hier das Datenblatt: 
http://focus.ti.com/lit/ds/symlink/tlv320aic3101.pdf
Auf Seite 35 gehts los mit dem Thema, das mich [uns hier] beschäftigt.
Ich habe 16bit Koeffizenten und den vorgegeben Filter.

Die gewünschten 6 Koeffizenten sind, wie oben geschrieben:
a0 = 1
a1 = -1,98912252587406
a2 = 0,989181317356648
b0 = 1,01182878630458
b1 = -1,98885781422416
b2 = 0,977617242701964

Die vorhanden eines Fitlers 5 Koeffizenten würde ich wie folgt 
programmieren:
N0..3 = b0..3
D1..2 = a1..2
a0 wird nicht gebraucht, da es auf 1 ist. Ich denke dafür steht die 
32768.
Problem: z.B a1 passt nicht in das Zahlenformat. (< -1.0)
Eure lösung bisher: skalieren. Alles durch 2 oder 4.
geht aber nicht, da a0 ja dann auch skaliert werden müsste. a0 steht 
aber als "1.0" fest. Das Ergebnis des Filters im Nachhinein durch das 
eigentliche a0 zu teilen geht ja nicht, da die Verarbeitungsreihnfolge 
feststeht und ich darauf keinen Zugriff habe.

In einem Softwarefilter wäre das kein Problem. Hier habe ich NUR die 
koeffizienten.


Wie löst man das Problem..?
Gast #828904
Lesenswert?

Nein, a0 muss nicht mitskaliert werden. a0 bleibt 1, alle anderen 
Koeffizienten durch eine passende 2er-Potenz. Hinter dem Filter 
multiplizierst du wieder mit der besagten 2er-Potenz. Warum 2er-Potenz? 
Weil die i.d.R. mit einem Shift realisiert wird. Und warum geht das so? 
Siehe Anhang.  ;^)
Angehängte Dateien:
OP #828920
Lesenswert?

Versteh doch.. WIE soll ich denn in einer vorgegebenen 
Verarbeitungsreihnfolge, so wie es der DAC implementiert, im Nachhinein 
einen Shift einbauen??? Dafür gibt es weder einen Shift-Koeffizenten 
noch ein Register, wo man sowas ablegen könnte... Bei mir gibt es kein 
"Hinter dem Filter.." da kommt dann der DAC
das genau ist doch mein Problem.. sonst würde ich doch nicht fragen ;-)
Gast #828922
Lesenswert?

Ähhhh, stop mal eben. Also von dir angegebenen Koeffizienten a0 bis b2 
möchtest du gerne implementieren mit dem fest verwursteten Filter? Daher 
kannst du nicht mehr an a0 ran? (Hatte ich vorher nicht realisiert.) Die 
Filterfunktion wird von ti/BB wie in deinem ersten Anhang angegeben. Und 
dort steht vor a1 und b1 eine 2*...also musst du dein a1 und b1 ohnehin 
durch 2 teilen - und dann passts doch?! Oder sehe ich hier etwas falsch?
Gast #829058
Lesenswert?

Ich habe mir jetzt nicht alles zur Gänze zu Gemüte geführt, aber was mir 
auffällt ist, dass dein Filter eine Verstärkung von +20dB hat. Ich kenne 
das nicht so. Wie klingt es denn mit dem gerundeten Koeffizient? 
Verzerrt oder eigentlich sauber, nur etwas zu "hell"?
Ich kenne das nur so, dass der Frequenzgang maximal 0dB ist (und hiermit 
den Zahlenbereich ausreizt). Nun dann, das musst du selbst wissen ob das 
so gewollt ist oder nicht. Zusätzlich stellt sich mir die Frage, welche 
Aufgabe und Spezifikationen (f_pass, f_stop, f_s, Dämpfung im 
Sperrbereich) dieses Filter haben soll. Davon ausgehend kann ich mir das 
nochmal angucken.
#829114
Lesenswert?

Ich kenne mich leider mit digitalen Filtern und deren Eigenschaften 
nicht so recht aus :-(

Angaben wie "f_pass, f_stop, f_s, Dämpfung im Sperrbereich" kann ich dir 
nicht geben. Ich bewerte lieber nach "Klingt <-> klingt nicht" ;-)

Die 20dB Anbhebung funktionieren. Ich muss das Eingangssignal vorher 
skalieren (Faktor 1/6) damit ein Short nicht überläuft.
Das ganze ließe sich sicherlich auch mit 0dB Verstärkung und im 
restlichen Bereich eine Abschwächung um 20dB ohne das Signal zu 
skalieren.
Sollte das Selbe rauskommen. Das wäre quasi ein HighShelf mit 20dB 
Abschwächung ab 100Hz anstatt ein LowShelf bis 100Hz.

Wenn die Senkung des Pegels die Koeffizienten zu meinem Vorteil 
verändert... her mit den Vorschlägen! Ich kenne mich leider nicht genug 
aus... ich weiß nichtmal ob die HighShelf-Variante von der Charakterisik 
einen Skalierten (leidergemachten) LowShelf ersetzen kann...

@Die 3 Fragezeichen: Wenn du andere Formeln hast zur Berechnung solcher 
Filter... mit anderen/mehr parametern... her damit... experimentiere 
gerne :-)

MFG
Gast #829176
Lesenswert?

Du möchtest also die Bässe kräftiger machen, ergo LowShelf. Du hast die 
Frage

> Wie klingt es denn mit dem gerundeten Koeffizient? Verzerrt oder eigentlich
> sauber, nur etwas zu "hell"?

leider nicht beantwortet.

Im Anhang habe ich dir mal ein Schema gelegt welches erklärt, was ich 
mit den Parametern meine. Wie hoch ist deine Abtastfrequenz f_s?
Angehängte Dateien:
#829234
Lesenswert?

Danke für dein Bild :-)

fs ist variabel, aber z.Z. 44100Hz.
Es klingt einfach babarisch nach "WummsWumms" ;-) Und ich muss das 
Eingangssignal mit rund 1/90 skalieren, damit Short nicht überläuft. 
Heller wird dabei nix. bzw es verschwindet im Bass.

Auch die anderen Parameter des Filters sollen variabel gehalten werden. 
Die Berechnung soll später direkt auf dem µC erfolgen..

Wäre schön, wenn du helfen könntest. Am liebsten wären mir Formeln.. 
keine fertigen Koeffizienten ;-)

MFG

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren