Ich habe in meiner Anwendung an einem einfachen Tiefpassfilter für die Messung <100 Hz gearbeitet. Aber bis jetzt kämpfe ich mit der Theorie dahinter. Es ist cool, dass ich es zum Laufen gebracht habe, aber ich würde es wirklich genießen, wenn ich wüsste, wie / warum es funktioniert.
Ich habe folgenden Code gefunden:
void getLPCoefficientsButterworth2Pole(const int samplerate, const double cutoff, double* const ax, double* const by)
{
double PI = M_PI;
double sqrt2 = sqrt(2);
double QcRaw = (2 * PI * cutoff) / samplerate; // Find cutoff frequency in [0..PI]
double QcWarp = tan(QcRaw); // Warp cutoff frequency
double gain = 1 / ( 1 + sqrt2 / QcWarp + 2 / ( QcWarp * QcWarp ) );
by[2] = ( 1 - sqrt2 / QcWarp + 2 / ( QcWarp * QcWarp ) ) * gain;
by[1] = ( 2 - 2 * 2 / ( QcWarp * QcWarp ) ) * gain;
by[0] = 1;
ax[0] = 1 * gain;
ax[1] = 2 * gain;
ax[2] = 1 * gain;
}
Berechnung der Koeffizienten. Dann 'passiere' ich sie in den Audio-Samples folgendermaßen:
xv[2] = xv[1];
xv[1] = xv[0];
xv[0] = pData[j];
yv[2] = yv[1];
yv[1] = yv[0];
yv[0] = (ax[0] * xv[0] + ax[1] * xv[1] + ax[2] * xv[2]
- by[1] * yv[0]
- by[2] * yv[1]);
pData[j] = yv[0];
Um ein Tiefpass-Design zu erhalten.
Ich frage mich ein paar Dinge:
- Ich empfange die Audio-Samples in einem einfachen float * -Array. Was ist diese Float-Nummer? Das einzige was ich sehe ist eine Zahl, wie ist das ein Stück Klang?
- Der Code verwendet frühere Berechnungen (drei davon) in der neuen Berechnung pro Stichprobe. Bedeutet das, dass die ersten beiden Datenproben nicht richtig gefiltert werden? (nicht, dass es wichtig wäre, weil es nur 2 Proben sind, aber ich frage mich nur)
- Beim Versuch, alles zu lernen, fand ich einige Formeln für den Butterworth-Filter (2. Pol). Wie spiegeln sich diese Formeln in diesem Code wider? Keine der gefundenen Formeln enthält diese Berechnungen, die Sie in der Funktion 'getLPCoefficientsButterworth2Pole ()' sehen können.
lowpass-filter
c
Niek van der Steen
quelle
quelle
Antworten:
Das Array number * ist ein Zeiger auf das Array. Es ist eine einzelne Zahl, die die Adresse des ersten Elements des Arrays von Gleitkommawerten enthält.
Normalerweise ist die Anfangsbedingung (dh die anfänglichen 'vergangenen' Elemente von x und y) 0, aber wenn ihre Werte nicht gleich 0 sind, ist dies auch kein großes Problem, da die Anfangsbedingungen nach einer Weile keine Auswirkung auf die Ausgabe haben Signal für jeden stabilen Filter. Und Ihr Filter ist offensichtlich stabil.
Eine Tiefpassübertragungsfunktion zweiter Ordnung mit Butterworth-Charakteristik und Grenzfrequenz (mit in Hertz) ist gegeben durchωein= 2 ∗ π∗ fein fein
Dabei ist die Abtastfrequenz. Dies ist erforderlich, da die Frequenzachse der analogen Signale ( ) für zeitdiskrete Signale ( ) auf den zulässigen Frequenzbereich abgebildet werden muss . Da diese Transformation die Frequenzen , müssen wir die gewünschte analoge Grenzfrequenz aus der gegebenen Grenzfrequenz im zeitdiskreten Bereich :fs 0 ≤ f≤ ∞ 0 ≤ f≤ fs/ 2 fd
Wenn Sie (2) in (1) einfügen, erhalten Sie
mit
wo ich . Die Übertragungsfunktion (3) entspricht der Zeitbereichsgleichungα = tan( ωd2)
Wie Sie sehen können, gibt es eine gewisse Ähnlichkeit mit Ihrem Code. Es gibt jedoch auch einige Unterschiede, und Sie sollten den Frequenzgang Ihres Filters überprüfen. Ich denke, dass die obigen Gleichungen korrekt sind, aber es liegt an Ihnen, sie zu überprüfen und zu entscheiden, welche Version die richtige ist.
quelle
Sie haben gefragt, wie ein Tiefpassfilter funktioniert, und erwähnt, dass der Filter frühere Werte Ihrer Daten verwendet. Dies ist eine nicht technische Diskussion darüber, was in einem Tiefpassfilter passiert.
Der Tiefpassfilter nimmt unterschiedliche (zeitlich verschobene) Ansichten Ihres Signals auf, skaliert sie und addiert sie. Sie können sich vorstellen, Ihr Signal dreimal zu zeichnen, wobei eines aktuell ist, das zweite um eine Abtastzeit und das dritte um zwei Abtastzeiten verschoben ist.
Bei niedrigen Frequenzen sehen alle Ansichten sehr ähnlich aus (die Verschiebung um ein einzelnes Sample ändert sich kaum, wenn Sie sich zu einem bestimmten Zeitpunkt auf dem Signal befinden). In diesem Fall addieren sich die drei Versionen auf konstruktive (oder zumindest zerstörungsfreie) Weise, sodass das Signal den Filter durchläuft.
Wenn Sie sich nun zu höheren Frequenzen bewegen, wird jede verschobene Version des Signals zu jedem Zeitpunkt (Abtastpunkt) deutlicher und kann sogar das Vorzeichen umkehren. Bei diesen höheren Frequenzen heben sich die drei Versionen Ihres Signals auf (werden destruktiv hinzugefügt), sodass das Signal gedämpft wird.
Verschiedene Arten von Filtern sorgen dafür, dass diese Art von konstruktiver / destruktiver Interferenz über geeignete Frequenzbänder stattfindet, um Tiefpass-, Bandpass- oder Hochpassfilter zu erzeugen.
quelle
Es hängt davon ab, wie Sie es wollen. Für mich habe ich in implementiert
C
. Also habe ich Filterkoeffizienten bei dermatlab
Verwendung generiertfirls
. Dann habe ich diese Filterkoeffizienten in einem Array gespeichert und diese Filterkoeffizienten dann an die Filterfunktion in übergebenC
. Inmatlab
es ist ganz einfach , um die Filterkoeffizienten erzeugt wird , und dann die Faltungsoperation verwenden oder einen bestimmten Filter verwenden. Aber in mussC
man auch den Filter implementieren. Ich für meinen Teil muss es für DSPs tun, also implementiert inC
und habe die Ergebnisse bei dermatlab
Verwendung der mex-Funktion erhalten. Verwenden Sie diesen Befehl, um die Koeffizienten zu berechnenmatlab
:quelle