Im Moment bin ich auf der Suche nach einer schnellen Implementierung für
einen IIR-Bandpass für einen 32Bit Festkomma ARM.
Die Filterparameter sind Güte Q und Resonanzfrequenz fg.
Ein zweipoliger IIR lässt sich folgendermaßen realisieren:
Wenn dir 3dB/oct ausreichen, kannst du einen einfachen Low-Pass und
einen High-Pass hintereinander setzen.
Das benötigt dann 2 Multiplikationen insgesamt.
>Wenn dir 3dB/oct ausreichen, ...
An so was habe ich auch schon gedacht. Der Anwendungsfall ist ein Filter
für einen Audiosynthesizer. Ich vermute, dass 3dB/Octave da nicht so gut
klingen.
Bei Synthesizern wird oft eine Resonanzbandpass verwendet, den man knapp
an der Schwinggrenze bewegt und interessante Effekte gibt.
Moin,
Bei Synthies ist's wohl oefter ein Tiefpass, dessen Guete so eingestellt
wird, dass er eine Resonanzueberhoehung hat.
Genau das kann aber bei IIR Filtern problematisch werden: wenn die Pole
nah am Einheitskreis sind - also Obacht geben und Abstand halten :-)
Und bei 4 Additionen und 5 Multiplikationen pro Sample fuer ein
Audiofilter auf einem ARM - was willste denn da noch effizienter
gestalten? Das waere wohl ein Thema, wenn du das auf einem 8bit AVR
laufen lassen wolltest.
Gruss
WK
>Und bei 4 Additionen und 5 Multiplikationen pro Sample fuer ein>Audiofilter auf einem ARM - was willste denn da noch effizienter>gestalten?
Für einen Synth kann man nie Rechenleistung genug haben. Es läuft ja
nicht nur der eine Filter, sondern eventuell mehrere und viele andere
Algorithmen in Echtzeit.
Moin,
Jaa, ist schon klar. Aber was willst du denn da noch gross einsparen?
Viel wichtiger ist, ob das so hinhaut mit der Genauigkeit und den
Frequenzgaengen, die du da rausholen willst. Und was du an Rechenpower
brauchst, um die Koeffizienten (idealerweise bei jedem Sample) neu zu
berechnen. Du wirst ja das Filter variieren wollen, waehrend da die
Samples durchrauschen.
Hier hab' ich das mal gemacht:
Beitrag "Re: adaptiv IIR Filter Koeffizienten ändern, wie?"
Und da berechne ich die Koeffizenten nur grob naerungsweise jeweils
durch ein Polynom 2. Ordnung. Das ist monsterungenau und wenn man haben
will, dass der Filterfrequenzgang sich eher exponentiell (a.k.a. z.B.
1V/Octave) zu einem Steuerwert verschiebt, muss man mit Polynomen
hoeherer Ordnung arbeiten, damit das wenigstens halbwegs noch passt.
Oder gleich tatsaechlich mit Exponentialfunktionen.
Das braucht viel mehr Rechenbums als das olle Filter alleine.
Gruss
WK
Moin,
chris schrieb:> Praktisch wäre noch, wenn die Berechung der Koeffizienten in> Abhängkigkeit von f und Q im C-Code ersichtlich wäre.
Das Leben ist kein Ponyhof. Ich hab' da halt ein Cauer(=elliptisches)
Filter als Prototyp hergenommen. Da gibts direkt kein Q, das koennte man
hoechstens durch den Ripple im Durchlassbereich modellieren.
Aber was denkst du wohl, was diese Zeilen machen, wenn f die
Grenzfrequenz ist?
1
/* calc. filter coeff: */
2
a2 = 2.3357*f*f + 2.1763*f -2.1513;
3
a3 = 1.0347*f*f -1.1111*f + 1.0368;
4
5
b2 = 0.539422*f*f + 0.184865*f -0.039056;
6
b3 = 0.2632061*f*f + 0.0759953*f + 0.0014133;
> Wenn ich es richtig sehe, lässt sich der Rechenaufwand auf 3> Multiplikationen reduzieren:
Da sehe ich hauptsaechlich Berechnungen im Zeitkontinuierlichen.
Und - ja, wenn du mit speziellen Faellen von Filtern arbeitest, kanns
schon sein, dass da evtl. was gespart werden kann. Bei den Filtern in
meinem Fall ist z.B. immer b1=b3. Vielleicht spart das eine
Multiplikation beim Filtern, aber vielleicht kriegst du dann auch
leichter arithmetische Ueberlaeufe.
Und im Vergleich zum Aufwand, den du treiben musst, um aus f und Q die
Koeffizienten zu berechen ist das halt nix.
Das was ich da mach' mit den quadratischen Funktionen, ist ja nur eine
grobe Naerung an die Wirklichkeit. Weil die Wirklichkeit halt auch
Winkelfunktionen, Divisionen etc. enthaelt und so ein Polynom auch
einfacher in Festpunktarithmetik zu giessen ist, so man es dann machen
muss/will.
tl,dr:
Das Hirnschmalz und die Rechenpower steckt in der Berechnung der
Koeffizienten und nicht im Berechnen der Samples, die aus dem Filter
purzeln.
Gruss
WK
Auf dem ARM, welcher sowohl "Signed Multiply Accumulate" und "Signed
Multiply Subtract" Instructions hat wird die ganze Mathematik zu nur
fünf Instructions kompilieren.
Im Vergleich dazu wird das Laden der Samples und Koeffizienten mehr Zeit
brauchen.
Im Musikbereich werden (Software-)Synthesizer oft über MIDI Controller
gesteuert, die haben eine Auflösung von 128 Stufen bei den
Potentiometern, und das hat bisher noch keinen Musiker gestört.
Statt die Koeffizienten "live" zu berechnen, kann man also auch 128
Filtereinstellungen vorab berechnen, und die Koeffizienten im Flash/RAM
ablegen.
Für 128 Stufen, 5 Koeffizienten und 32-Bit sind hierfür 2,5 KB nötig.
Wenn man weiche Übergänge zwischen den 128 Stufen haben möchte, kann man
für den Übergang 2 Nachbar-Filter parallel laufen lassen, und (schnell)
zwischen dem einen zum anderen faden.
Moin,
Ja, klingt praktikabel. Insbesondere, wenn man mal hoehere
Flankensteilheiten haben will.
Die Tabellen werden wahrscheinlich unangenehm gross, wenn man nicht nur
die Frequenz sondern auch noch Guete oder sonstwas einstellbar macht.
Aber zur Not musses halt auf ne SD-Card ausgelagert werden :-)
Gruss
WK
Joe F. schrieb:> Im Musikbereich werden (Software-)Synthesizer oft über MIDI Controller> gesteuert, die haben eine Auflösung von 128 Stufen bei den> Potentiometern, und das hat bisher noch keinen Musiker gestört.
Doch, das hat schon viele Musiker gestört. Mit so wenigern Stufen sind
nicht einmal Lautstärken unhörbar stufenlos zu verstellen, geschweige
denn Filterkoeffizienten. Die müssen in den Geräten immer geglättet und
hochskaliert werden. Um das zu lindern gibt es non-registered-parameters
mit 14 Bit.