Forum: Digitale Signalverarbeitung / DSP / Machine Learning schneller IIR Bandpass


von chris (Gast)


Lesenswert?

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:
1
 y(n) = b1*x(n) + b2*x(n-1) + b3*x(n-2) - a2*y(n-1) - a3*y(n-2);

Das wären also 2 Additionen, 2 Subtraktionen und 5 Multiplikationen.

Geht es auch effizienter?

von Tobias (. (Gast)


Lesenswert?

wenn es gelingt, einige Parameter identisch zu formulieren, vielleicht?

von Joe F. (easylife)


Lesenswert?

Wenn dir 3dB/oct ausreichen, kannst du einen einfachen Low-Pass und 
einen High-Pass hintereinander setzen.
Das benötigt dann 2 Multiplikationen insgesamt.

von chris (Gast)


Lesenswert?

>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.

von Dergute W. (derguteweka)


Lesenswert?

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

von chris (Gast)


Lesenswert?

>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.

von Dergute W. (derguteweka)


Lesenswert?

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

von chris (Gast)


Lesenswert?

>Hier hab' ich das mal gemacht:

Schön, dass Du ein Beispiel gepostet hast.

https://www.mikrocontroller.net/attachment/highlight/334507

Praktisch wäre noch, wenn die Berechung der Koeffizienten in 
Abhängkigkeit von f und Q im C-Code ersichtlich wäre.

Wenn ich es richtig sehe, lässt sich der Rechenaufwand auf 3 
Multiplikationen reduzieren:
https://www.native-instruments.com/fileadmin/ni_media/downloads/pdf/VAFilterDesign_2.0.0a.pdf
( S.122 ).

von Dergute W. (derguteweka)


Lesenswert?

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

von Nils P. (torus)


Lesenswert?

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.

von Joe F. (easylife)


Lesenswert?

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.

von Dergute W. (derguteweka)


Lesenswert?

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

von Rolf S. (audiorolf)


Lesenswert?

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.

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.