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
a0 auf 1 lassen, anschließend (hier um 2) verstärken (Linksshift).
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?
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.
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.
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..?
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. ;^)
Na hoppala, da hat sich der copy-paste-Fehler eingeschlichen. $^) Aber nu....
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 ;-)
Ä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?
aha! klingt gut. hab ich auch noch nicht bemerkt. Kenne mich mit den Formeln niocht so aus.. hab nicht gewusst, dass das unnormal bzw eine implementierungshilfe ist ;-) Mist ist aber immernoch: N0 == b0 == 1.01 -> :-(
Wo hast du die Koeffizienten her? Einfach auf 1 runden ist nicht ratsam, siehe Anhang (rot = gerundet).
Koeffizientenberechnung: Siehe Erster Post. Der Code entspringt: Beitrag "Zeitvariante Filter" Auf eins gerundet hab ichs auch schon versucht ;-) Das Resultat klang ungefähr.. nuja ;-) wie der rote Graph ;-) Aber das stellt jetzt schon wirklich ein Problem dar, oder? Mist :-(
@albi ganz oben in der formel wird ja 2xN1 und 2xD1 erwähnt. teilst du dein b1 bzw. a1 durch 2 bleibst du unterhalb von 1.0. sehe ich das richtig ? somit müsste/könnte es passen.
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.
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
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?
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.