Forum: Digitale Signalverarbeitung / DSP / Machine Learning FFT Fehlerhaft?


von Markus (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen!

Ich beschäftige mich noch nicht lange mit DSP, versuche mich aber im 
Moment damit die FFT zu verstehen und anzuwenden. Ich habe ein 
Testprogramm geschrieben, welches mir ein Signal generiert und 
anschlißend dieses Signal wieder analysiert. (Nicht unbedingt ein 
Sinnvolles Programm, aber so möchte ich die FFT testen)

Hier stoße ich auch auf ein Problem. In meinem Test erzeuge ich eine 
Sinusfunktion mit 15Hz. Als Bitrate habe ich 22050 gewählt. Wenn ich 
diese Funktion nun in meiner FFT analysiere mit 16384 Punkten bekomme 
ich kein exaktes Ergebnis. Als Ergebnis der FFT bekomme ich 12 Hz und 
nicht 15Hz.

Ist die FFT nicht so genau das es zu solchen Abweichungen kommt oder 
muss an meinem Sourcecode ein Fehler sein?

Im Anhang ein Screenshot meines Testprogrammes. Wenn ihr vermutet das es 
an meinem Source liegt und die FFT eigentlich exakt 15Hz als Ergebnis 
liefern müsste kann ich den source auch gerne mal posten.

Ich hoffe mir kann jemand helfen.
Vielen Dank schonmal!

Markus

von Günter -. (guenter)


Lesenswert?

Erklär doch mal warum du so krumme Zahlen für Bitrate und FFT Länge 
genommen hast.

Wenn ich deine Nummern nehme dann sieht deine FFT nicht eine volle Zahl 
an Sinusschwingen und dann entsteht der sogenannten "Leakage"-Effekt.

Mach mal folgendes, nehme 16170 Samples von deinem Signal und dann setze 
die restlichen Samples bis 16384 auf 0. Wenn du jetzt die FFT 
berechnest, sollte es genau einen Strich im Frequenzspektrum geben.

von Markus (Gast)


Lesenswert?

Vielen Dank für Deine Antwort!

Ich habe so einen Krummen wert für die Samples genommen weil die FFT 
doch eine 2er Potenz als Anzahl der Samples braucht oder habe ich da was 
falsch verstanden?

Die Bitrate habe ich gewählt weil 22050 wenn ich richtig informiert bin 
eine Gängige Bitrate bei Audiodateien ist...?

Ich habe die felder im array meiner eingangsschwingung von 16170 bis 
16384 auf 0 gesetzt, aber das Ergebnis ist das Selbe.

von Unit* (Gast)


Lesenswert?

Was ist das für eine Software/Simulations-/Entwicklungsumgebung? Ein 
bisschen Leckage ist zu sehen, wenn Du das Eingangssignal maschinell 
erzeugt hast, müsste es genau sein, und es müsste keine Leckage geben. 
Daher tippe ich eher auf Programmierfehler.

von Markus (Gast)


Lesenswert?

Ich habe das ganze in C++ unter Windows geschrieben, das Signal erzeuge 
ich selber und schreibe die Daten direkt in ein Array:
1
  float frequency = 15.0f;
2
  float phase = 0.0f;
3
  float bitrate = 22050.0f;
4
  float amplitude = 100;
5
  float x = frequency * 2.0f * PI / bitrate;
6
  for(int cnt = 0; cnt < bitrate; cnt++)
7
    buffer[cnt]=(double)(sin(phase + cnt * x) * amplitude);

Ich bin jetzt nicht 100% sicher ob es bei der Berechnung so starke 
abweichungen geben kann das es solche Verschiebungen in der Analyse 
gibt... Oder mache ich beim Signal generieren was falsch??

Habt ihr noch eine Idee was ich testen könnte? Ich arbeite übrigens im 
Moment mit dieser FFT Funktion ( 
http://www.codeproject.com/KB/audio-video/waveInFFT.aspx )

Deshalb vermute ich das zumindest die Analyse Funktion fehlerfrei sein 
sollte... Allerdings schließe ich nicht aus das ich nicht noch irgendwo 
fehler mache ;)

von Max (Gast)


Lesenswert?

Falls Du 16384 Punkte hast und 22050 Sampl pro sek. sind, ist das 
Abtastfenster 16384/22050 0,743 Sekunden.

Die erste Spektrallinie ist 1/0,743 also 1,345 Hz.

Im Bild ist 12 Hz angezeigt. Falls Du 12 Spektrallinien mit 1,345 
multiplizierst ensteht 20 Hz.

Noch immer nicht 15 Hz. Vielleicht ist noch ein zweites Problem beim
Generator oder bei der Skalierung.

Gruß
MAX

von Markus (Gast)


Lesenswert?

Mh... 12 * 1,345 ergibt 16,15
Wäre das eine logischere ungenauigkeit? Ich weiß halt nicht wie exakt 
die Rückrechnung sein muss wenn das Eingangssignal selber generiert ist 
und eigentlich sauber sein sollte.

Nochmal eine kleine Verständnisfrage am Rande. Nach der Analyse von 
einer 16384 Punkte-FFT bekomme ich doch ein Spektrum von 8192 Punkten 
als Ergebnis oder? Entspricht dann jeder Punkt (wie Max es vorgerechnet 
hat) 1,345 Hz oder muss ich von den 8192 Punkten ausgehen und somit 1 / 
(8192 / 22050) dafür rechnen?

von Markus (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe es jetzt mal mit max's ansatz versucht, und das Ganze macht 
durchaus Sinn ;)

Ich habe jetzt mal eine Funktion generiert die aus 15Hz, 30 Hz und 50 Hz 
zusammengesetzt wurde.

Schaut man sich das Spektrum an komme ich auf folgende werte

12 * 1,345 = 16,14 Hz
23 * 1,345 = 30,94 Hz
38 * 1,345 = 51,11 Hz

Also passt einigermaßen...
Gibt es noch Möglichkeiten die Werte genauer zu bekommen?

von Max (Gast)


Lesenswert?

Eine Verbesserung.

Falls nicht genau die Schwingungen  in das Abtastfenster passen, (z.B. 
30,5 Schwingungen im Fenstster), erhält man mehrere Spektallinien.
Falls man darüber ein Parabel (x²) zieht und aus dieser Gleichung das 
Maximum berechnet, wird es genauer.

Etwas stutzig mach mich, dass bei 15 Hz fast nur eine Spektrallinie ist, 
bei
30 Hz ein breiteres Spektrum zu sehen ist.

**********************


Feinauflösung eines Spektrums:
Durch folgende Operationen wird das Spektrum eines
Signals genauer als mit einer einfachen FFT bestimmt.
Hamming Fenster, Zero Padding, Power Spektrum,
Peak Detektor.


Falls Du LabVIEW hast
http://schulen.eduhi.at/htlbraunau/lehrer/ploetz/Labbsp/index.html

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.