Forum: Digitale Signalverarbeitung / DSP / Machine Learning Implementieren Filter in C von http://t-filter.appspot.com


von Raph (Gast)


Lesenswert?

Hallo Zusammen

grad dabei den Filter von http://t-filter.appspot.com
in mein uC Programm zu implementieren.

Ich habe Probleme die Funktionen in double MM_FILTER ordentlich 
aufzurufen und die Funktions Parameter zu übertragen bzw zu lesen. 
Jedenfalls meine Compiler will das nicht compilieren


daweilst lese ich meine C Bücher...
1
C-Code
2
void BABYBEFilter_init(BABYBEFilter* f) {
3
  int i;
4
  for(i = 0; i < BABYBEFILTER_TAP_NUM; ++i)
5
    f->history[i] = 0;
6
  f->last_index = 0;
7
}
8
9
void BABYBEFilter_put(BABYBEFilter* f, double input) {
10
  f->history[f->last_index++] = input;
11
  if(f->last_index == BABYBEFILTER_TAP_NUM)
12
    f->last_index = 0;
13
}
14
15
double BABYBEFilter_get(BABYBEFilter* f) {
16
  double acc = 0;
17
  int index = f->last_index, i;
18
  for(i = 0; i < BABYBEFILTER_TAP_NUM; ++i) {
19
    index = index != 0 ? index-1 : BABYBEFILTER_TAP_NUM-1;
20
    acc += f->history[index] * filter_taps[i];
21
  };
22
  return acc;
23
}    
24
25
      
26
double MM_FILTER ( double SENSOR) // Lowpass http://t-filter.engineerjs.com/
27
{
28
29
 //BABYBEFilter_put(&BABYBEFilter,SENSOR);  //Mein Versuch
30
31
//BABYBEFilter_get(&BABYBEFilter,SENSOR);//Mein Versuch
32
33
return SENSOR;
34
35
      };

von Nop (Gast)


Lesenswert?

Magst Du vielleicht auch noch die Fehlermeldungen des C-Compilers 
reinkopieren?

Und btw., ist double wirklich nötig? Selbst wenn Dein Controller eine 
FPU hat (wie Cortex-M4 etwa), dann kann die auch nur float, und double 
in Software ist schon arg langsam.

von Nop (Gast)


Lesenswert?

Was mir auch so schon auffällt, worüber ich als Compiler meckern würde:

Einerseits hast Du:
void BABYBEFilter_init(BABYBEFilter* f)

Dann versuchst Du:
BABYBEFilter_put(&BABYBEFilter,SENSOR);

Das Problem ist, daß BABYBEFilter oben ein Datentyp ist, während Du das 
unten als Variable gebrauchen willst. Das kann nicht gehen.

Zweitens benutzt Du in MM_FILTER die Eingabe SENSOR zwar als Paramater 
für die beiden Filter-Aufrufe, Dein return-Wert ist aber einfach SENSOR. 
MM_FILTER wird also einfach den Wert zurückgeben, den sie erhalten hat, 
also eine Identitätsfunktion.

von Mark B. (markbrandis)


Lesenswert?

Nop schrieb:
> Zweitens benutzt Du in MM_FILTER die Eingabe SENSOR zwar als Paramater
> für die beiden Filter-Aufrufe, Dein return-Wert ist aber einfach SENSOR.
> MM_FILTER wird also einfach den Wert zurückgeben, den sie erhalten hat,
> also eine Identitätsfunktion.

Naja die zwei auskommentierten Zeilen werden nicht kompiliert haben. 
Deswegen sind sie wohl auskommentiert ;-)

von Reinhard M. (Gast)


Lesenswert?

Der Original C++ Code lässt sich problemlos compileren.

Vermutlich gibt es bei der C- Implementierung eine
struct BABYBEFilter o.ähnlich.

Ohne Kenntnis darüber, bleibt nur die Glaskugel.

Aber einfach mal geraten:

BABYBEFilter_put(&f,SENSOR);

von Mark B. (markbrandis)


Lesenswert?

Reinhard M. schrieb:
> Der Original C++ Code lässt sich problemlos compileren.
>
> Vermutlich gibt es bei der C- Implementierung eine
> struct BABYBEFilter o.ähnlich.

Nicht nur vermutlich. Diese Struktur ist in der automatisch generierten 
Datei BABYBEFilter.h definiert. Die Header- und die C-Datei bekommt man 
von der oben genannten Website erstellt.

von Mark B. (markbrandis)


Lesenswert?

So klappt es  besser:
1.) Im eigenen Code die autogenerierte Header-Datei einbinden.
2.) Im eigenen Code Speicher für das Filter anlegen.
3.) Danach die verschiedenen Funktionen aufrufen. Siehe Beispiel.

1
#include "BABYBEFilter.h"
2
#include <stdio.h>
3
4
int main()
5
{
6
    BABYBEFilter filter1;
7
    
8
    BABYBEFilter_init(&filter1);
9
    
10
    BABYBEFilter_put(&filter1, 2.0);
11
    
12
    double filtered_value = BABYBEFilter_get(&filter1);
13
    printf("Filtered value: %f\n", filtered_value);
14
    
15
    return 0;
16
}

von W.S. (Gast)


Lesenswert?

Raph schrieb:
> daweilst lese ich meine C Bücher...

Naja, lies lieber dort: "http://www.dspguide.com/";
Das Ganze gibt's auch als PDF zum Herunterladen.

Ich hab vergeblich versucht, in deinem Geposteten irgend einen Sinn zu 
erkennen. Gleiches gilt für die genannte Internet-Seite. Hab dort mal 
versucht, einen Bandpaß für 100 Hz .. 2.7 kHz bei 44.1 kHz Samplerate 
einzugeben - geht nicht.

Was für ein Filter soll das eigentlich werden?
Mein Vorschlag wäre ein FIR Filter und den Filterkernel als sin(x)/x mit 
anschließendem Blackman-Fenster. Das geht leicht, auch in C - und es 
liefert ne ordentlich glatte Durchlaßkurve.

Rezept für Bandpaß:
- ersten Tiefpaß für untere Eckfrequenz berechnen, Blackman applizieren
- zweiten Tiefpaß für obere Eckfrequenz berechnen, Blackman applizieren
- beide Tiefpässe normieren
- Spektralinversion auf zweiten Tiefpaß
- beide Tiefpässe addieren, ergibt Bandsperre
- Spektralinversion auf resultierende Bandsperre, ergibt Bandpaß.
- fertig.

W.S.

von Raph (Gast)


Lesenswert?

Hey Bitte den Thread nicht Offtopic machen .

Ist keine DSP Problem sondern eine C Sache über Funktions Überageb und 
Structs.

Gruß

RL

von Raph (Gast)


Lesenswert?

Leider meckert der Compiler bei BABYBEFilter_put(&f,SENSOR);

f ist nicht declariert.Das C Beispiel läßt sich super compilieren.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

W.S. schrieb:
> Mein Vorschlag wäre ein FIR Filter und den Filterkernel als sin(x)/x mit
> anschließendem Blackman-Fenster. Das geht leicht, auch in C - und es
> liefert ne ordentlich glatte Durchlaßkurve.

Wenn man nur einen Hammer hat, sehen alle Probleme aus wie Naegel :-)


Raph schrieb:
> Ist keine DSP Problem sondern eine C Sache über Funktions Überageb und
> Structs.

Warum postest du dann im DSP-Unterforum und nicht unter:

"PC-Programmierung
Programmierung auf PCs, Algorithmen, allgemeine Programmierfragen ohne 
direkten Mikrocontroller-Bezug."?

Unn? Watissnu? Geht jetzt dein lustiges C-Programm? Woran hings?


Gruss
WK

von Reinhard M. (Gast)


Lesenswert?

Kennt er die Variable nicht ??

Wie meckert der Compiler ???

Poste halt mal alles und lass Dir nicht alles aus der Nase ziehn!

von Mark B. (markbrandis)


Lesenswert?

Raph schrieb:
> Leider meckert der Compiler bei BABYBEFilter_put(&f,SENSOR);
>
> f ist nicht declariert.Das C Beispiel läßt sich super compilieren.

Na dann deklariere es eben. Wie das geht, habe ich im Beispiel oben doch 
gezeigt. Wenn Du damit nicht klarkommst, musst Du erstmal die Grundlagen 
lernen.

von W.S. (Gast)


Lesenswert?

Dergute W. schrieb:
> Wenn man nur einen Hammer hat, sehen alle Probleme aus wie Naegel :-)

Nö.

Der TO will ein Filter selber programmieren und hat sich dazu auf eine 
Inet-Seite eingelassen, die mir ausgesprochen seltsam und nicht 
zielführend zu sein scheint.

Anstatt hier über C-Probleme mit einer Breitseite irgendwelcher 
"Baby"-Filter-Funktionen zu diskutieren, halte ich es für eher 
angebracht, mal den tieferen Sinn und Zweck der Übung kundzutun. Auf 
diesem Wege käme man der Lösung des Problems möglicherweise eher näher - 
oder?

W.S.

von MaWin (Gast)


Lesenswert?

W.S. schrieb:

> Der TO will ein Filter selber programmieren und hat sich dazu auf eine
> Inet-Seite eingelassen, die mir ausgesprochen seltsam und nicht
> zielführend zu sein scheint.

Wieso? Auf der Seite brauch man nur die Eckdaten eines Filters angeben. 
Danach kann der komplette C-Code kann heruntergeladen werden. Dann nur 
noch kompilieren. Fertig.

von Raph (Gast)


Lesenswert?

Ich werde Troll sachen erst gar nicht durchlesen.

F ist wohl Zeiger auf die Structur BABYBEFilter

der richtige Syntax ist mir noch nicht ganz klar beim Aufruf


(
1
#ifndef BABYBEFILTER_H_
2
#define BABYBEFILTER_H_
3
4
/*
5
6
FIR filter designed with
7
 http://t-filter.appspot.com
8
9
sampling frequency: 2000 Hz
10
11
* 0 Hz - 400 Hz
12
  gain = 1
13
  desired ripple = 5 dB
14
  actual ripple = 4.1393894966071585 dB
15
16
* 500 Hz - 1000 Hz
17
  gain = 0
18
  desired attenuation = -40 dB
19
  actual attenuation = -40.07355419274887 dB
20
21
*/
22
23
#define BABYBEFILTER_TAP_NUM 21
24
25
typedef struct {
26
  double history[BABYBEFILTER_TAP_NUM];
27
  unsigned int last_index;
28
} BABYBEFilter;
29
30
void BABYBEFilter_init(BABYBEFilter* f);
31
void BABYBEFilter_put(BABYBEFilter* f, double input);
32
double BABYBEFilter_get(BABYBEFilter* f);
33
34
#endif
35
36
C-Code

von Mark B. (markbrandis)


Lesenswert?

Raph schrieb:
> Ich werde Troll sachen erst gar nicht durchlesen.
>
> F ist wohl Zeiger auf die Structur BABYBEFilter
>
> der richtige Syntax ist mir noch nicht ganz klar beim Aufruf

Eine Möglichkeit für Deklaration und Aufrufe habe ich doch in diesem 
Thread gepostet. Was daran hast Du nicht verstanden?

Wenn Du hier keine "Troll sachen" lesen willst, dann solltest Du 
vielleicht mal damit anfangen, selbst nicht wie ein Troll zu schreiben.

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.