Forum: Digitale Signalverarbeitung / DSP / Machine Learning Fragen zu FFT mit Festkomma-Arithmetik


von Ralf (Gast)


Lesenswert?

Hallo,

ich beschäftige mich gerade mit der FFT-Implementierung auf einem ARM 
Cortex-M3. Dazu verwende ich die CMSIS-DSP Bibliothek und habe mich für 
die Festkomma-Implementierung entschieden (konkret das Q15-Format).

Über einen 10-Bit-ADC lese ich ein Sinussignal ein. Das Ergebnis wird um 
fünf Stellen nach links geschoben, damit möchte ich erreichen, dass der 
Maximalwert des ADC dem Maximalwert des Q15-Formats entspricht (ist 
nicht ganz korrekt, weil Nullen nachgeschoben werden, aber zumindest nah 
dran).

Die Implementierung an sich läuft soweit, ich bekomme plausible 
Ergebnisse (soweit ich das beurteilen kann). Ich will das ganze auch 
noch separat nachrechnen, damit ich das komplett nachvollziehen kann.

Umgekehrt interessiert mich aber, ob ein FFT-Bin des Ergebnisses 
überhaupt den Maximalwert des Festkomma-Datentyps erreichen kann. Beim 
DC-Anteil (Bin 0) ist das m.E. der Fall, wenn eben der ADC permanent am 
Anschlag ist, aber wie schaut das bei den die Frequenzen angebenden Bins 
aus?

Kann man denn aus dem Maximalwert bzw. der maximalen Skala der 
Eingangssignale den resultierenden Maximalwert der FFT-Ausgabe 
berechnen? Das wäre z.B. nützlich, wenn man das ganze grafisch auf einem 
Display darstellen möchte, damit man das obere Ende kennt und passend 
"zoomen" kann.

Ralf

von Ralf (Gast)


Lesenswert?

Nachtrag:
Ich hab das grad mal durchgerechnet, anhand einer kleinen FFT mit 8 
Eingangswerten, jeweils 1+0i. Ich komme im ersten Bin auf 8, alle 
anderen 0.

Was heißt das nun bezogen auf einen Festkomma-Datentyp? Im Q15-Format 
kann man 8 ja nicht darstellen. Heisst das, dass ich das Ergebnis 
eigentlich noch durch 8 ( = Anzahl der Samples) teilen muss? Im 
Q15-Format also um drei Stellen nach links schieben?

Ralf

von Detlef _. (detlef_a)


Lesenswert?

>>>dass der Maximalwert des ADC dem Maximalwert des Q15-Formats entspricht

Ja, dann bekommst Du einen overflow, wie Du mit deinem 1+0*i Beispiel 
auch gesehen hast. Eine FFT der Länge 2^n hat n 'stages' und von stage 
zu stage gewinnst Du ein Bit hinzu. Bei Q15 hast Du 15Bit Dynamik, ne 
1024er FFT macht Dir 9 Bit (oder 10 hm?) hinzu, Du darfst also maximal 
mit 6Bit ADC Werten reingehen. In jeder stage machst du auch die cos/sin 
Multiplikationen, das ist bei der nötigen Rechendynamik ebenfalls zu 
berücksichtigen.

Das ganze ist auch signalabhängig: Dein reiner 'DC' versammelt sich 
natürlich im ersten bin, ein reiner Sinus in einem einzigen bin. 
Breitbandiges Rauschen verteilt sich auf alle bins, da hat mein keine 
'peaks' im Frequenzbereich und kommt nicht so nahe an die Grezen des 
Zahlenbereichs.

Wie die von Dir benutzte 'Bibliothek' das macht weiss ich nicht. Es gibt 
auch Implementationen, die kucken in jeder stage ob sie an der 
Aussteuerungsgrenze sind und renormalisieren.

Pi mal Daumen: m Bit ADC, 2^n Bit FFT Länge

Bitbreite =m+n+2 Sicherheitsbit, Vorzeichen ist ggf auch noch ein Bit.

Beim Rechnen der Sin/Cos auch nicht allzu viel stutzen: 15Bit*15Bit plus 
Summe sind 31Bit, die möglichst wenig abschneiden, also nicht wieder 
auch 15 Bit runternormieren, sonst Rauscht die Geschichte.

Cheers
Detlef

von Ralf (Gast)


Lesenswert?

Hi Detlef,

>> dass der Maximalwert des ADC dem Maximalwert des Q15-Formats
>> entspricht
> Ja, dann bekommst Du einen overflow, wie Du mit deinem 1+0*i Beispiel
> auch gesehen hast. Eine FFT der Länge 2^n hat n 'stages' und von stage
> zu stage gewinnst Du ein Bit hinzu. Bei Q15 hast Du 15Bit Dynamik, ne
> 1024er FFT macht Dir 9 Bit (oder 10 hm?) hinzu, Du darfst also maximal
> mit 6Bit ADC Werten reingehen. In jeder stage machst du auch die cos/sin
> Multiplikationen, das ist bei der nötigen Rechendynamik ebenfalls zu
> berücksichtigen.
Okay, ich verwende eine 256er FFT, also könnte ich auch auf Q31 gehen. 
Das heisst aber dann, dass ich das Eingangssignal nicht schieben sollte.
Wie sorgt man dann dafür, dass das ganze "gescheit" auf einem Display 
angezeigt werden kann? Den Bin mit dem höchsten Wert ermitteln und 
darauf zoomen?
Aktuell mach ich das so, dass ich den Maximalwert auf den 
Displaybereich, den ich vorgesehen habe umrechne. Nur erreichen die Bins 
dann gerade mal etwa 20% Ausschlag (Testsignal Sinus, Offset 0.5, 
Amplitude 0.5).
Deswegen auch die Frage, unter welchen Bedingungen denn eigentlich der 
Maximalwert erreicht wird.

> Das ganze ist auch signalabhängig: Dein reiner 'DC' versammelt sich
> natürlich im ersten bin, ein reiner Sinus in einem einzigen bin.
> Breitbandiges Rauschen verteilt sich auf alle bins, da hat mein keine
> 'peaks' im Frequenzbereich und kommt nicht so nahe an die Grezen des
> Zahlenbereichs.
>
> Wie die von Dir benutzte 'Bibliothek' das macht weiss ich nicht. Es gibt
> auch Implementationen, die kucken in jeder stage ob sie an der
> Aussteuerungsgrenze sind und renormalisieren.
>
> Pi mal Daumen: m Bit ADC, 2^n Bit FFT Länge
>
> Bitbreite =m+n+2 Sicherheitsbit, Vorzeichen ist ggf auch noch ein Bit.
>
> Beim Rechnen der Sin/Cos auch nicht allzu viel stutzen: 15Bit*15Bit plus
> Summe sind 31Bit, die möglichst wenig abschneiden, also nicht wieder
> auch 15 Bit runternormieren, sonst Rauscht die Geschichte.
Die Sin/Cos Werte werden auch von der Lib zur Verfügung gestellt. Ich 
vermute mal, dass Sättigung da durchaus beachtet und korrigiert wird.

Ralf

von Detlef _. (detlef_a)


Lesenswert?

Hi,

10Bit ADC, 256er FFT sind 18+x Bit, da passt dann Q31.

>>>
Deswegen auch die Frage, unter welchen Bedingungen denn eigentlich der
Maximalwert erreicht wird.
<<<<

Wenn sich alles in einem bin versammelt, also bei einem Sinus der 
richtigen Frequenz.

Anzeige: Muss Du entscheiden, entweder feste Skalierung und schlechte 
Aussteuerung oder variable Skalierung und immer bis zum Anschlag 
ausgesteuert. Das ist Geschmacksfrage.

Wird schon.

Cheers
Detlef

von Ralf (Gast)


Lesenswert?

Hi Detlef,

> 10Bit ADC, 256er FFT sind 18+x Bit, da passt dann Q31.
Danke erstmal für die Erläuterung ganz oben, das war mir erst gar nicht 
richtig bewusst, dass sich das pro Stufe aufaddiert.

>> Deswegen auch die Frage, unter welchen Bedingungen denn eigentlich der
>> Maximalwert erreicht wird.
> Wenn sich alles in einem bin versammelt, also bei einem Sinus der
> richtigen Frequenz.
Ich glaub ich hab die Frage falsch formuliert: das o.g. ist klar, die 
Frequenz mit der höchsten Amplitude ergibt den höchsten Wert für einen 
Bin. Meine Frage bezog sich darauf, wann der Maximalwert des Datentyps 
(also Q15 bzw Q31) erreicht wird bzw ob das überhaupt geht. Das mit dem 
Schieben muss ich nochmal schauen, wie dann bei meiner aktuell festen 
Skalierung das Ergebnis aussieht. Wenn es dann immer noch "nix" ist, 
dann werd ich vielleicht doch auf variable Skalierung gehen.
Muss ich bzgl der Schieberei noch etwas beachten -> dass ich mit rein 
reellen Werten in die FFT gehe, spielt ja keine Rolle, oder? Nicht dass 
dann auch noch Auswirkungen hat.

> Anzeige: Muss Du entscheiden, entweder feste Skalierung und schlechte
> Aussteuerung oder variable Skalierung und immer bis zum Anschlag
> ausgesteuert. Das ist Geschmacksfrage.
Ja, ich glaub dazwischen gibt's nix =)

> Wird schon.
Japp, vielen Dank für die bisherige Hilfe.

Ralf

von Detlef _. (detlef_a)


Angehängte Dateien:

Lesenswert?

Hi,

ich habe mal in meinen Archiven gestöbert und angehängten Code zu einer 
16 Bit integer-FFT gefunden, Zwischenergebnisse in 32 Bit. Die 
FFT-Längen von 2^5 - 2^10 sind abgedeckt. Die FFT macht die oben 
erwähnte dynamische Skalierung: Drht Overflow wird renormiert.

Das ist kein Hexenwerk, statt mich mit den Tücken von 'Bibliotheken' zu 
befassen programmier ich sowas lieber selber, das steht in jedem 
halbwegs fitten Lehrbuch.

Cheers
Detlef

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.