| Autor |
Nachricht |
mael15
Mitglied
Benutzerprofil
Anmeldungsdatum: 04.01.2009
Beiträge: 227
|
mael15 Mitglied
11:17:32 24.07.2012 Titel: |
tiefpass koeffizienten berechnen |
Zitieren |
hallo zusammen,
ich schreibe ein programm, welches ein xy signal auf dem bildschirm darstellt. dieses signal möchte ich in echtzeit glätten, wofür ein tiefpass filter sinn macht. zu diesem zweck habe ich mit von dem simplen programm winFilter folgenden c code generieren lassen:
| Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | /**************************************************************
WinFilter version 0.8
http://www.winfilter.20m.com
akundert@hotmail.com
Filter type: Low Pass
Filter model: Butterworth
Filter order: 5
Sampling Frequency: 1000 Hz
Cut Frequency: 300.000000 Hz
Coefficents Quantization: float
Z domain Zeros
z = -1.000000 + j 0.000000
z = -1.000000 + j 0.000000
z = -1.000000 + j 0.000000
z = -1.000000 + j 0.000000
z = -1.000000 + j 0.000000
Z domain Poles
z = -0.238827 + j -0.699060
z = -0.238827 + j 0.699060
z = -0.174643 + j -0.315932
z = -0.174643 + j 0.315932
z = -0.158384 + j -0.000000
***************************************************************/
#define NCoef 5
float iir(float NewSample) {
float ACoef[NCoef+1] = {
0.10837789384895716000,
0.54188946924478576000,
1.08377893848957150000,
1.08377893848957150000,
0.54188946924478576000,
0.10837789384895716000
};
float BCoef[NCoef+1] = {
1.00000000000000000000,
0.98532523927923832000,
0.97384933183676425000,
0.38635655864844887000,
0.11116384057834201000,
0.01126351245656587500
};
static float y[NCoef+1]; //output samples
static float x[NCoef+1]; //input samples
int n;
//shift the old samples
for(n=NCoef; n>0; n--) {
x[n] = x[n-1];
y[n] = y[n-1];
}
//Calculate the new output
x[0] = NewSample;
y[0] = ACoef[0] * x[0];
for(n=1; n<=NCoef; n++)
y[0] += ACoef[n] * x[n] - BCoef[n] * y[n];
return y[0];
} | |
der programmcode wird generiert, nachdem man in winFilter die grenzfrequenz eingegeben hat. ich möchte aber in meinem programm über einen regler die grenzfrequenz einstellbar machen. danach müsste ich dann die koeffizienten selber neu berechnen. wie mache ich das?
ich habe schon sehr ausgiebig hier im forum gesucht und gegoogelt, finde aber leider nur für mein verständnis viel zu mathematische erklärungen gefunden oder beiträge, in denen matlab benutzt wird und der filter nicht zur laufzeit änderbar ist oder anwendungen auf audiosignale.
z.b. gibt es hier einen guten beitrag http://www.c-plusplus.de/forum/p140825 mit fertigem c++ code (!) http://www.musicdsp.org/showArchiveComment.php?ArchiveID=243, aber das liefert mir keine guten ergebnisse, vermutlich wegen | Zitat: | | There are some minima and maxima defined, to make ist sound nice in all situations. | Mein signal ist eben kein audio signal.
mein filter soll optimalerweise stark abregeln, also nach http://en.wikipedia.org/wiki/Butterworth_filter#Transfer_function z.b. 5. ordnung sein, falls das zu kompliziert wäre ginge auch einer 2. ordnung.
nur eben wie berechne ich die koeffizienten?
danke!
EDIT: es geht mir nicht um exakt diese koeffizienten im quellcode, sondern allgemein funktionierende. |
Zuletzt bearbeitet von mael15 am 14:51:12 24.07.2012, insgesamt 1-mal bearbeitet |
|
 |
krümelkacker
Mitglied
Benutzerprofil
Anmeldungsdatum: 10.08.2010
Beiträge: 2223
|
krümelkacker Mitglied
09:20:05 27.07.2012 Titel: |
|
Zitieren |
Ein paar Kommentare:
- Die Speicherung des Filter-Zustandes als static-Variablen innerhalb einer Funktion ist extrem unschön. Stattdessen könntest Du das als struct machen. Siehe Folie 19
- Wenn du die Filterparameter zur Laufzeit anpassen willst, dann müssen diese Parameter natürlich auch Teil des Zustandes sein (wie auch in dem verlinkten Codebeispiel). Es ist auch sehr empfehlenswert, den Filter in mehrere "kleine" (niedriger Ordnung) zu faktorisieren, die man dann hintereinander schaltet, wenn du die Parameter dynamisch ändern willst. Denn es besteht die Gefahr, dass ein Filter höherer Ordnung kurzzeitig instabil beim Umschalten auf andere Parameter wird. Da du ja schon die Pole und Zeros kennst, teilst du sie einfach auf in mehrere Biquad-Filter, wobei ein Biquad dann bis zu zwei Zeros und Pole haben kann. Damit du reellwertige Filterkoeffizienten bekommst, musst du bei komplexwertigen Zeros oder Polen die komplex konjugierten paaren.
- Die Grenzfrequenz des Butterworth-Filters könntest du per "Frequenzwarping" erhöhen oder erniedrigen. Das ist äquivalent zum Butterworth-Design mit einer anderen Grenzfrequenz. Ich müsste irgendwo Matlab Code haben, der dieses Frequenz-Warping auf den Filterkoeffizienten durchführt. So kompliziert ist das eigentlich gar nicht, habe nur gerade keine Zeit, das nachzugucken. Aber vielleicht findest du ja unter dem Stichwort "frequency warping" etwas im Netz. Man kann es jedenfalls direkt auf den Filterkoeffizienten machen, oder die Pole und Zeros verschieben und die dann in Filterkoeffizienten umrechnen.
|
|
|
|
 |
KasF
Mitglied
Benutzerprofil
Anmeldungsdatum: 14.12.2004
Beiträge: 2492
|
KasF Mitglied
11:37:24 27.07.2012 Titel: |
|
Zitieren |
Hast du Matlab?
Muss es Butterworth sein, oder ist das zufällige gewählt? |
_________________ Um C++ zu beherrschen muss man schon for( ;; ) fragen ob er genug Zeit für einen hat ...
|
|
 |
mael15
Mitglied
Benutzerprofil
Anmeldungsdatum: 04.01.2009
Beiträge: 227
|
mael15 Mitglied
11:53:02 27.07.2012 Titel: |
|
Zitieren |
danke für eure antworten!
@KasF:
ich habe leider kein matlab. wäre es denn damit möglich, die veränderung der koeffizienten beim verstellen der grenzfrequenz abzubilden?
es muss nicht butterworth sein, ich hätte nur gerne einen tiefpass mit recht starker dämpfung. im moment habe ich 24dB, weniger sollten es nicht sein.
im moment habe ich mir http://www.musicdsp.org/showone.php?id=243 angepasst, funktioniert auch, finde ich aber nicht so ideal.
@krümelkacker:
die speicherung des filterzustandes würde ich tatsächlich nicht static machen. der code war nur ein ansatz, wie er mir von winFilter erzeugt wurde.
für das aufteilen in mehrere biquad filter wie von dir beschrieben fehlt mir leider das mathematische verständnis. am besten wäre ein algorithmus, der die koeffizienten berechnet. um instabilität zu vermeiden würde ich während der berechnung die darstellung des signals aussetzen. da es kein audiosignal ist würden auch kurze extremwerte nicht stören.
ich befürchte, auch das frequency warping übersteigt meine mathematischen fähigkeiten |
|
|
|
 |
KasF
Mitglied
Benutzerprofil
Anmeldungsdatum: 14.12.2004
Beiträge: 2492
|
KasF Mitglied
12:29:44 27.07.2012 Titel: |
|
Zitieren |
Und was willst du dann mit den Koeffizienten machen? Dich interessiert doch nur das Ergebniss für verschiedene Grenzfrequenzen, oder? Das Codestück von musicdsp gibt dir doch auch die Koeffizienten. Die Codeecken mit min/max kannst du ja abschneiden , wenn du glaubst, dass sie dein Ergebnis negativ beeinflussen.
Ja, mit Matlab kannst du dir dann auch die Koeffizienten anzeigen lassen. Aber wie gesat, willst du überhaupt die Koeffizienten, oder doch nur das gefilterte Ausgangssignal? |
_________________ Um C++ zu beherrschen muss man schon for( ;; ) fragen ob er genug Zeit für einen hat ...
|
|
 |
Unregistrierter
|
Unregistrierter
12:47:56 27.07.2012 Titel: |
|
Zitieren |
Was ich für solche Fälle (variable Grenzfrequenz) ganz geschickt finde ist: http://www.earlevel.com/m ....... al-state-variable-filter/
Bei sehr hohen Grenzfrequenzen ist das Filter nicht zu empfehlen (kann instabil werden). Aber die "Koeffizienten" berechnen sich sehr einfach. Für kleine Grenzfrequenzen kann man sich den sin() auch noch sparen. |
|
|
|
 |
mael15
Mitglied
Benutzerprofil
Anmeldungsdatum: 04.01.2009
Beiträge: 227
|
mael15 Mitglied
15:10:41 27.07.2012 Titel: |
|
Zitieren |
| Tim schrieb: | | Bei sehr hohen Grenzfrequenzen ist das Filter nicht zu empfehlen (kann instabil werden). |
Interessanter Artikel, danke! Die stabilitätsgrenze 1/6 der samplerate ist dann aber leider zu niedrig.
| KasF schrieb: | | Dich interessiert doch nur das Ergebniss für verschiedene Grenzfrequenzen, oder? |
Ja, das ist richtig. Mein erster Post kam noch vor der jetzigen Lösung mit dem angepassten musicdsp code. ich dachte nur, es würde irgendwie einfacher gehen. aber denn belasse ich es einfach dabei.
danke für eure ideen! |
|
|
|
 |
Unregistrierter
|
Unregistrierter
15:18:44 27.07.2012 Titel: |
|
Zitieren |
| mael15 schrieb: | | Tim schrieb: | | Bei sehr hohen Grenzfrequenzen ist das Filter nicht zu empfehlen (kann instabil werden). |
Interessanter Artikel, danke! Die stabilitätsgrenze 1/6 der samplerate ist dann aber leider zu niedrig. |
Wie im Artikel steht: Oversampling. Rechentechnisch bist du wahrscheinlich trotzdem besser als wenn du dir klassisch die Koeffizienten für deine Biquads ständig neu berechnest.
Edit: Auch wenn es für dich wahrscheinlich nicht relevant ist, aber das Ding hat sehr gute Fixkomma-Eigenschaften. |
Zuletzt bearbeitet von Unregistrierter am 15:20:12 27.07.2012, insgesamt 1-mal bearbeitet |
|
 |
mael15
Mitglied
Benutzerprofil
Anmeldungsdatum: 04.01.2009
Beiträge: 227
|
mael15 Mitglied
15:25:41 27.07.2012 Titel: |
|
Zitieren |
oversampling wird zu aufwändig, weil der tiefpass in echtzeit auf maximal 4 kanäle mit jeweils maximal 10k sample rate angewendet wird.
aber trotzdem danke für die anregung. |
|
|
|
 |
Unregistrierter
|
Unregistrierter
16:13:03 27.07.2012 Titel: |
|
Zitieren |
Wie gesagt, ich bezweifle, dass Oversampling hier mehr kostet als die Koeffizienten für die Biquads zu berechnen. Aber kein Problem, nimm was du willst
btw, Koeffizientenberechnung:
T = Abtastzeit
§K = tan(\frac{\omega_g T}{2})§
§a_0 = \frac{K^2}{1+\sqrt 2 K + K^2}§
§a_1 = \frac{2K^2}{1+\sqrt 2 K + K^2}§
§a_2 = \frac{K^2}{1+\sqrt 2 K + K^2}§
§b_1 = \frac{2(K^2 - 1)}{1+\sqrt 2 K + K^2}§
§b_2 = \frac{1-\sqrt 2 K + K^2}{1+\sqrt 2 K + K^2}§
aus:
3. Ausgabe
PS: Aufpassen: Die Benennung der Koeffizienten ai und bi ist nicht immer identisch. Im oberen Fall sind die ai die Vorwärtskoeffizienten. |
Zuletzt bearbeitet von Unregistrierter am 16:14:02 27.07.2012, insgesamt 1-mal bearbeitet |
|
 |
|
Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.
|
|
|
|
|