Grüß euch
Ich hab momentan ein kleines Problem mit der Implementierung eines
IIR-Filters in der aktuellen Version der CMSIS Library für einen
STM32F4. Später sollen mit dem Filter einmal Soundfiles bearbeitet
werden, vorab wollte ich aber nur die Geschwindigkeit erproben und mich
ein wenig in die Libs einarbeiten.
Zum Design des Filters und dessen Koeffizienten hab ich MATLAB
herangezogen. Dort funktioniert das Filter auch bereits wunderbar und
ich kann mir vom Frequenz-/Amplitudengang bis zum Spektrum des
gefilterten Signals alles ansehen...
MATLAB liefert auch gleich die passenden Filterkoeffizienten, die direkt
in den Code gefüttert werden können.
Seitens der CMSIS DSP Library hab ich mich für die float64 Variante des
Biquads in der Form "Direct Form II Transposed" entschieden. Laut meiner
Information sei diese die für Gleitkomma-Darstellung stabilste Form.
Details zur Implementierung findet man direkt bei ARM:
http://www.keil.com/pack/doc/CMSIS/DSP/html/group___biquad_cascade_d_f2_t.html
In Code sieht das ganze nun so aus
1 | float64_t testInput_f64[320] = { * wollt ich euch ersparen... * };
|
2 | float64_t testOutput_f64[320] = {0};
|
3 | const float64_t coeffs[5] = { 0.0168191501070571,
|
4 | 0.0336383002141143,
|
5 | 0.0168191501070571,
|
6 | -1.60109239418362,
|
7 | 0.668368994611848};
|
8 |
|
9 | static float64_t biquadStateBandF64[4]; // one stage -> 4x state variables {x[n-1], x[n-2], y[n-1], y[n-2]}
|
10 |
|
11 |
|
12 | int main(void)
|
13 | {
|
14 | /* Variables for df2T */
|
15 | arm_biquad_cascade_df2T_instance_f64 S1;
|
16 | float64_t *inputF64, *outputF64;
|
17 |
|
18 |
|
19 | /* Link */
|
20 | inputF64 = &testInput_f64[0];
|
21 | outputF64 = &testOutput_f64[0];
|
22 |
|
23 |
|
24 | /* Initialize biquad f64 */
|
25 | arm_biquad_cascade_df2T_init_f64 (&S1, 1, (float64_t *) &coeffs[0], &biquadStateBandF64[0]);
|
26 |
|
27 | /* Run biquad */
|
28 | arm_biquad_cascade_df2T_f64(&S1, inputF64, outputF64, 320);
|
29 |
|
30 | }
|
Soweit sogut. Zwar rechnet mir der M4 das Filter brav durch, nur leider
stimmen die Werte im Ausgangsbuffer überhaupt nicht mit den gefilterten
Werten von MATLAB überein. Noch dazu scheint das Filter nicht einmal
stabil zu sein, da die Werte recht schnell absurd steigen und auch
alternieren...
Hat jemand eine Idee woran das liegen kann?
Ich hab mich ursprünglich absichtlich für float64 entschieden, da diese
Darstellung numerisch ident (oder zumindest fast ident) mit der
Standard-Darstellung in MATLAB sein sollte? Wo passiert hier also der
Fehler?
lg
Vinci