Forum: Digitale Signalverarbeitung / DSP / Machine Learning digitaler Mittelwertfilter


von Sil M. (silwan)


Lesenswert?

Hallo Leute,

ich habe mit Hilfe von Xilinx, Virtex und System Generator eine 
FFT-Verarbeitung gebaut (funktioniert soweit).

Nun möchte ich aber die resultierenden Betragsdaten noch im FPGA 
mitteln, damit ich allfälliges STörrauschen wegkriege aus den Nutzdaten 
(d.h. 50-100 FFT's nehmen und mitteln).

Hat jemand ne schlaue Idee dazu? Ich hätte zu einem digitalen FIR-Filter 
tendiert, da dieser ja eigentlich als Tiefpass bzw. Mittelwertfilter für 
N Samples verwendet werden kann...

hat da jemand Erfahrung?

Vielen Dank und Grüsse

von Ras F. (rasfunk)


Lesenswert?

Im Prinzip hast Du Recht: ein FIR-Filter kann verwendet werden, um den 
Mittelwert zu bilden. In Deinem Fall musst Du darauf achten, dass Du 
nicht das gesamte Spektrum filterst, sondern immer nur die einzelne 
Spektralkomponente bzw. FFT-Linie mittelst.

Je nachdem, wie viele FFT-Linien Du benötigst, würde ich Dir aber doch 
schwer empfehlen, keinen herkömmlichen FIR-Filter (womöglich aus der 
Xilinx-Library) zu verwenden. Richte Dir stattdessen einen 2-Port Memory 
Block her, der so groß ist, dass er ein einzelnes Spektrum aufnehmen 
kann (Data Width der Speicherworte muss je nach Anzahl der Additionen 
erhöht werden!). Wenn ein neues Sample eines neuen Spektrums reinkommt 
(z.B. als Stream), lies den bisherigen Wert des RAMs über den Leseport 
aus, addiere mit einem Adder das neue Sample, und schreib das ganze an 
die gleiche Adresse über den Schreibport zurück.

Sobald Du 64 oder 128 Spektren aufaddiert hast, kannst Du das Ergebnis 
auslesen (Division kommt durch Shiften um 6 bzw. 7 umsonst), und den 
Speicher wieder auf 0 setzen.

Braucht ein bisschen Kniffelei mit der Logik, den Countern und 
möglicherweise mit Pipelining, aber sowas habe ich schon öfter mal 
implementiert.

von Ras F. (rasfunk)


Lesenswert?

Kleiner Nachtrag:

Ich bin jetzt davon ausgegangen, dass dann auch nur jedes 64te oder 
128te Spektrum benötigt wird. Falls die Anzahl der Eingangsspektren auch 
die Anzahl der Ausgangsspektren sein soll, ist vielleicht doch ein 
FIR-Filter die einfachste Lösung. Allerdings werden dann entsprechend 
viele Spektren im Register/Speicher vorgehalten, was ordentlich in die 
Resourcen geht.

Wie auch immer, mit dem FIR dann alle Filterkoeffizienten gleich 1/N, 
wobei N die Anzahl der Taps ist (oder auch: Summe aller Koeffizienten 
gleich eins).

von Sil M. (silwan)


Lesenswert?

jup, das ist richtig so. Ich ermittle mit dem FFT v6.0-Core (aus Xilinx 
bzw. Systemgenerator) jeweils das Spektrum aus konstant reinkommenden 
Audiodaten (via Ac97-Codec im Xilinx ML506-Board).

Da ich mit einem einzelnen Signal aufgrund des Mikrophonrauschens nix 
anfangen bzw. dieses nicht repräsentativ ist, muss ich ca. 50-100 
Spektren nehmen, diese mitteln und dazu ist mir einfach ein Fir-Filter 
in den Sinn gekommen... das geht einfach und ich habe in Xilinx 
systemgenerator einen Fir-Compiler, wo ich einen digitalen Tiefpass 
erstellen und das Rauschen rausfiltern kann.

Könntest du mir evtl noch etwas genauer erklären, wie du das mit den 
dualport-Ram jeweils gemacht hast? Das tönt noch interessant, egal ob 
ich nun jedes einzelne oder nur jedes x-te Betragsspektrum verwenden 
möchte...

Wenn ich das richtig verstanden habe, schlägst du vor, nur jedes 64 oder 
128 zu addieren und nach 64 bzw. 128 Additionen mit 6 bzw. 7 zu shiften 
(bzw ne Division zu machen). Weshalb schlägst du das vor? Ich habe eine 
fsample von 48kHz und eine Trafobreite von N=1024... evtl würde das bei 
mir ziemlich gut klappen so!

Grüsse & merci für eine Info

von Ras F. (rasfunk)


Lesenswert?

Ich hab zuerst eine Frage: Wozu brauchst Du das Spektrum? Es handelt 
sich nur um das Betragsspektrum, oder? Machst Du das nur zum Anzeigen, 
oder willst Du im Frequenzbereich noch etwas Filtern? Bastelst Du zur 
Zeit nur mit den Systemgeneratoren oder hast Du auch schon selbst 
VHDL-Komponenten erstellt?

Ansonsten nochmal die Idee mit dem Mittelwertbildner etwas 
detaillierter:

Angenommen, Du hast 8 Betragsspektren mit je 8 Linien (fiktives 
Zahlenbeispiel):

Spektrum 0: 1 0 1 20 2 3 1 1
Spektrum 1: 0 2 4 21 3 2 0 0
Spektrum 2: 3 3 0 18 8 1 3 1
Spektrum 3: 2 2 1 15 4 4 5 2
Spektrum 4: 3 1 7 25 6 3 2 4
Spektrum 5: 3 4 6 31 5 7 4 2
Spektrum 6: 5 3 4 17 3 6 1 2
Spektrum 7: 3 1 3 19 2 5 6 1

Der Punkt ist jetzt, dass die Mittelung die Linien der Spektren 
betrifft, d.h. Du müsstest als erstes den Stream "1 0 3 2 3 3 5 3" 
Filtern, nicht aber das erste Spektrum "1 0 1 20 2 3 1 1". Da erkennst 
Du leicht, dass bei 1024 Linien ziemlich genau 1024 FIR-Filter anfallen, 
und das geht in die Ressourcen.

Angenommen, die Samples haben jetzt alle eine Bitbreite von 8 Bit. Wir 
wollen 2^3 = 8 Spektren mitteln, d.h. 3 Bits kommen dazu. Macht 8+3 = 11 
Bits, gibt's nicht im FPGA, wird also zu 16 Bit im Accu. Nehmen wir 
einen Dual-Port-Ram her mit 16 Bit Wortbreite und 8 Worten Tiefe. Als 
erstes setzen wir den Null:

Addr 0: 0
Addr 1: 0
Addr 2: 0
Addr 3: 0
Addr 4: 0
Addr 5: 0
Addr 6: 0
Addr 7: 0

Nun kommt die erste Linie des Spektrums 0 daher: "1". Das wissen wir 
anhand irgendeines Zählerstandes oder so.

Nimm Wert an Addr. 0 (0) und addiere die Linie (1), speichere das 
Ergebnis (1) an Addr 0 (jetzt 1).

So geht das dann weiter für das ganze Spektrum, d.h. im Speicher steht 
jetzt im wesentlichen das este Spektrum:

Addr 0: 1
Addr 1: 0
Addr 2: 1
Addr 3: 20
Addr 4: 2
Addr 5: 3
Addr 6: 1
Addr 7: 1

Dann kommt die erste Linie des nächsten Spektrums. Schema wie oben, d.h. 
im Speicher steht dann Spektrum 0 + Spektrum 1. Genauso wird mit den 
anderen Spektren verfahren, bis im Speicher die Summe aller acht 
Spektren steht, d.h. jedes eintreffende Spektrum wird verarbeitet.

Aber erst nach 8 Spektren kannst Du ein gemitteltes Ausgabespektrum 
erstellen, indem Du den Speicher ausliest und durch 8 teilst (resp. um 3 
nach rechts shiftest). Gleichzeitig den Speicher auf Null setzen.

Bei 1024 Linien und 48kHz hast du so ca. 46,875 Spektren die Sekunde. 
Damit kämst Du bei einer Mittelung von 128 Spektren auf 0,366 gemittelte 
Ausgabespektren pro Sekunde, also alle 2,7 Sekunden ein Update.

Mir ist noch eingefallen, dass Du auch für jedes eingehende Spektrum ein 
gemitteltes Ausagebspektrum erzeugen kannst, indem Du den berechneten 
Durchschnittswert vor der Ausgabevom Accu abziehst und den Accu nie Null 
setzst. Argh, das ist jetzt irgendwei schlecht erklärt, vielleicht 
versteht ja trotzdem einer, was ich meine.

von Sil M. (silwan)


Lesenswert?

Hallo,

ja genau das suche oder versuche ich eigentlich umzusetzen... nur 
happerts gerade noch ein wenig... gestern hatte ich den Kopf zu voll, um 
das noch angehen zu können. =)

eben ... es sind nur Betragsspektren die aus einem xFFT-Core kommen in 
regelmässigan Abständen, gekennzeichnt mit einem DataValid. Dann diese 
Wert für Wert über die ganze Transformationsbreite N aufaddieren und 
durch N wieer dividieren... und fertig =) N ist bei mir 256 - 1024 
(einstellbar), Verarbeitsungsclockbase = 100MHz, AD-WAndlercloackbase = 
48KHz (AC97)...


kompliziert stimmt nicht, geht in Ordnung mit dem Beschrieb, der ist gut 
:) ... ist etwa so, wie ichs mir mal überlegt hatte... es muss nun 
einfach noch aufs Papier bzw. in den Systemgenerator gebracht werden... 
=) mit der Adressierung und dem Ganzen... das wird evtl etwas mühsam, 
aber machen muss ichs so oder so...


also denn, pack ich das mal an!
Grüsse & vielen Dank für die Infos,
silvan

von Hagen R. (hagen)


Lesenswert?

Und warum nicht deinen einen Eingangskanal schon vor der FFT per 
Tiefpass begrenzen und damit defakto mitteln ? Das was du aufwendig nach 
deiner FFT machen möchtest müsste auch einfach schon vor der FFT 
durchführbar sein.
Deine Methode macht doch nur dann Sinn wenn du im störenden Rauschen des 
Eingangssignales (und Rauschen ist auch alles was höher der 
Grenzfrequenz ist die du später am Ende mit deinem Tiefpass über die FFT 
Werte weghaben möchtest) durch die FFT noch weitere Informationen 
extrahieren möchtest. Ist dies nicht der Fall so sollte eine 
Tiefpassfilterung schon vor der FFT dein Problem auch lösen können und 
das einfacher.

Gruß Hagen

von Anon N. (fuechslein)


Lesenswert?

Total ACK. Ich war bisher nur zu faul zu schreiben aber um Rauschen raus 
zu filtern gibts es viel einfacher Moeglichkeiten wie deine 
Mittelmethode. Und dazu werden die warsch. noch viel effektiver sein.

Falls du nur kleines Rauschen hast (White Gaussian Noise) dann einfach 
ein normaler FIR TP.
Falls es ein bischen heftiger wird (Heavy tailed noise) dann zum Median 
filter greifen.

Wenn du ein "schoeneres" Spektrum willst. Mal nach Welsh PSD googeln. 
Dann macht so was aehnliches wie du.

von Sil M. (silwan)


Lesenswert?

Hallo Leute,

vielen Dank für die Rauschtipps. den Fir hab ich bereits eingebaut.

Wichtig wäre aber vor allem die Bruchbarkeit bzw. aussagekräftigkeit des 
Spektrums am Ausgang der FFt. Das der Vergleich des Ausgangspekturms mit 
einem Normspektrum stattfinden wird, ist es wichtig, dass ich ein 
aussagekräftiges Ausgangs-FFT habe... dies möchte ich dardurch 
erreichen, dass ich z.B. jedes 128 auffsummiere durch die Anzahl der 
Summierten... wäre auf jeden Fall aussagekärftiger als einfach 1 
enizelnes Spektrum zu verwenden.

oder gitbts da ne einfachere Umsetzung  (welsh PSd schau ich mir mal an, 
könnte was sein) um was brauchbares am Ausgang zu erhalten, was ich 
wieder auf ne regelung führen kann (nach dem Normspektrenvergleich)

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Hagen Re schrieb:
> Und warum nicht deinen einen Eingangskanal schon vor der FFT per
> Tiefpass begrenzen und damit defakto mitteln ?

Für das Spektrum muss jede Frequenzkomponente über die Zeit gemittelt 
werden, das ist etwas anderes als Filterung der einzlenen Samples im 
Zeitbereich.

Sil Mah schrieb:
> Wichtig wäre aber vor allem die Bruchbarkeit bzw. aussagekräftigkeit des
> Spektrums am Ausgang der FFt.

Mit Welch ist schon das richtige Stichwort gefallen, damit kannst du 
dann auch konkrete Aussagen über die Qualität (Bias, Varianz) deiner 
Spektrumsschätzung machen. Eine Alternative ist die rekursive Filterung. 
Das Thema wird in dem unfertigen Artikel [[Entwurf: Spektralanalyse mit 
der FFT]] angesprochen, ich bin aber noch nicht dazu gekommen daran 
weiterzuarbeiten.

von Sil M. (silwan)


Lesenswert?

Vielen Dank. Das tönt vernünftig, was der Aritkelentwurf bereits jetzt 
beschreibt. Noch die Nachfrage nach einer möglichkeit, dies zu 
implementieren in einen XILINX FPGA.
Du hast zwar schon Ansätze beschrieben, wie es sich einfach 
implementieren lässt (shifting, rekursiv mit einer Annäherung), 
allerdings sehe ich da noch Probleme mit der Wortbreite .. oder behälst 
du diese mittels dem ständigen shiften in Grenzen?

TP ist in Ordnung so ... habe mit fdatool von Matlab einen Filter nahc 
meinen Wènschen designt und via HDL ins Modell eingebunden.

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.