FMOD Fourier
-
Hallo,
ich habe mir mithilfe der FMOD-Library ( in C++) das Spektrum mithilfe der FFT von einem Audiostream geholt.
Nun habe ich aber folgendes Problem:
Das Spektrum fällt exponentiell (?) ab von den Tiefen Frequenzen zu den hohen. (Ist ja soweit auch logisch, falls ich mich nicht täusche, da die Oberfrequenzen viel geringer in die Wichtung fallen)
Gibt es eine Möglichkeit das Spektrum zu linearisieren?
Grüße xmf
-
Was meinst Du denn damit? Ich kann mit dem Wort „liniarisieren“ in dem Kontext nichts anfangen…
-
Ja, der Begriff ist hier sicherlich falsch in der Anwendung, ich probiere es mal andersherum:
Ich habe folgendes vor:
Mithilfe des Fourierspektrums möchte ich bestimmte Effekte in eienr graphsichen Anwendung auslösen.
Die Effekte sollen durch bestimmte Ton-Frequenzen getriggert werden
z.b. bei Bässen verwischt das Bild und bei hohen Tönen tritt eine Rotation ein.
Wie kann ich aus dem Fourier-Spektrum ablesen, was hohe und tiefe Töne sind?
-
Grundsätzlich bedeuten ja Werte, die weiter vom Mittelpunkt entfernt sind höhere Frequenzen und nähere bedeuten kleine Frequenzen. Ob da das mapping zu hoch/tiefen Tönen so direkt geht weiss ich jetzt nicht, aber ich denke das geht schon in etwa gut.
Kenne FT halt eher von der Bildbearbeitung.
-
Das hängt etwas davon ab, wie die FFT den Output organisiert. Die meisten Algorithmen packen in die ersten FFT-Länge/2 Bins die positiven Frequenzen und danach dann (bei reellen Eingangsdaten) spiegelverkehrt die negativen Frequenzen.
Wenn z.B. Deine FFT-Länge 1024 beträgt und der Output ein Array aus komplexen Werten (!) ist, dann liegt das positive Spektrum im Indexbereich von 0..511.
Ob das bei der FMOD-Lib so gehandhabt wird, weiß ich nicht. Da müsstest Du mal in die Doku gucken.
Die Transformation an sich ist linear. Häufig muss man allerdings mit der FFT-Länge normieren. Das hängt aber wieder von der Implementierung ab.
Wenn das Ergebnis bei Dir in den hohen Frequenzen abfällt, dann ist evtl. der Input bereits irgendwie gefiltert.
-
Hallo,
fft bedeutet eigentlich nur "schnelle Transformation". Welche konkrete Implementierung genommen wurde hängt vom Entwickler ab. Eine mögliche (und wahrscheinliche) Implementierung ist der Cooley-Tukey FFT, basierend auf dem Radix-2 Algorithmus. Anzahl der Inputs = Anzahl der Outputs und nur vielfache von 2, also 2x.
Die Ausgabe hat folgende Eigenschaften:
- Imaginärwerte sind punktsymmetrisch zur Mitte
- Realwerte sind achsensymmetrisch zur MitteInterpretation (linken N/2 Werte für x <=N/2)
- x-Wert ist die normierte Frequenz
- Betrag der komplexen Zahl (sqrt(Re*Re+Im*Im)) ist die Amplitude (Radius des erzeugenden Kreises)
- Argument ist die PhaseverschiebungDass nur die linken Werte interpretiert werden können liegt an dem Nyquist-Theorem, dass du mit N Samples nur die Frequenzen 0...N/2 bestimmen kannst. Ein Frequenz f könnte nämlich genauso eine falsch-interpretierte Frequen N-f sein, deshalb die symmetrischen Eigenschaften.
Beispiel:
N=64 Anzahl der Samples
s[N] Samplewertew(n) = 2π * n / N
s[i] = sin(w(i)*1.0) + sin(w(i)*2.0) + sin(w(i)*4.0) + sin(w(i)*8.0) + sin(w(i)*16.0)Also eine Überlagerung mit einer Schwingung mit Periodenlänge 64 Samples, eine Schwingung mit 32 Samples Periodenlänge, also zwei Perioden, usw... bis zur Schwingung mit Periodenlänge 4 Samples und 16 Perioden.
Die fft mit cooley-tukey bringt mir dann einen Ausschlag bei Sample 1,2,4,8,16 und symmetrisch bei N-1, N-2, N-4, N-8, N-16. Letztere sind die "falschen" Frequenzen, die wir hier ignorieren.
Hier sieht man dann auch, dass man keine Frequenzen mit einer Periodendauer unter zwei Samples darstellen kann, weil sonst keine Schwingung erkennbar ist.
Also:
|X[i]| ist die Amplitude, Im{X[i]} die Phasenverschiebung der normierten Frequenz die i Perioden hat.Willst also bei einem Lied die Bässe z.B. bis 100Hz haben, 44,1kHz Abtastung,
Dann mach eine FFT mit einer Länge, sodass der erste Bin für die Freqenzen bis 100Hz zuständig ist. D.h. du brauchst insgesamt 44100 / 100 Balken, also 441 Samples. Bei Cooley-tukey dann also 512 Samples, also hat dein erster Bin 44100Hz/512 Bandbreite = 0-86Hz, oder du nimmst halb so viel, dann hat dein erster Bin 44100Hz/256 Bandbreite = 176 Hz.Viel Spass damit, ich hoffe ich konnte helfen.
gruß Philipp
-
PhilippHToner schrieb:
...
Einiges ist richtig, vieles ist aber auch falsch.
Warum ich auf der Implementierung rumreite hat folgenden Grund:
Manche Bibliotheken ordenen das Ergebnis neu an. Zum Beispiel ist es recht üblich, dass ein sogenannter fft-shift durchgeführt hat, bei dem die negativen Frequenzen gespiegelt und vorne angefügt werden. Manche Bibliotheken bieten hierfür auch extra Funktionen an. Außerdem gibt es Unterschiede in der Normierung. Wenn es Dir auf den Pegel des Signals ankommt, dann brauchst Du diese Information.Falsche Frequenzen gibt es nicht. Das ein reelles Spektrum spiegelsymetrisch um 0 ist liegt nicht an falsch interpretierten Frequenzen. Es liegt daran, dass nicht bestimmbar ist, in welche richtung die Phase läuft. Betrachtest Du das ganze in der komplexen Ebene kannst Du also, von einem bestimmten Observationszeitpunkt ausgehend, für ein reelles Signal nicht sagen, ob der Drehzeiger im oder gegen den Urzeiger läuft. Nichtsdesotrotz sind weder die negativen Frequenzen noch die positiven Frequenzen falsch. Es ist sogar so, dass sich die Energie des Signals gleichmäßig auf den positiven Anteil und den negativen Anteil verteilt. Ohne den negativen Teil würde Dir bei einer Rücktransformation die Häfte der ursprünglich im Signal vorhandenen Energie flöten gehen.
-
Das ist genau das, was ich irgendwie in den online-Dokumenten (wikipedia oder math. Skripten von Hochschule) vermisse. Jeder rechnet und toll ist alles, aber irgendwie mal das Ergebnis deuten oder analysieren tut keiner. Zudem wissen wir hier irgendwie immernoch nicht, wie die Reihenfolge im Ergebnis ist.
Also ich habe nochmal meine fft Implementierung getestet und die zeigt Folgendes (N=64 Samples):
w(i)=2*pi*i/N1. x[i]=sin(w(i)*31.0), gerade noch machbar => Ausschlag bei X[31] = (0.0, 0.5) (analog dazu bei X[33]=(0.0,-0.5) )
2. x[i]=sin(w(i)*48.0), außerhalb des möglichen Frequenzbereichs => X[15] = (0.0, 0.5), X[47] = (0.0, -0.5) )Ich verstehe ehrlich gesagt nicht, wieso es keine Realteile gibt, obwohl es lauter "nicht-phasenverschobene" Schwingungen sind, hmmm.
gruß Philipp
-
Erzeugst Du zufällig ein analytisches (complexes) Signal? In manchen Mathematikprogrammen (Matlab z.B.) darfst Du i und j nicht als Variable benutzen, weil diese die imaginäre Einheit repräsentieren. Bei analytischen Signalen ist die Phasenbeziehung immer eindeutig, weshalb Du rein positive oder rein negative Spektren bekommst, je nach Vorzeichen der Phase.
-
Da es hier offenbar eher um die mathematischen Details als um die Programmiertechnik geht seid ihr hoffentlich einverstanden, wenn ich die Diskussion ins Matheforum verfrachte
-
Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ (auch C++0x, bzw. C++11) in das Forum Mathematik und Physik verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Nöö, also ich rede hier nur C++ Code, den ich halt mathematisch dargestellt hab, aber die fft wird ja richtig gefüttert. Komplexes Eingangssignal ohne Imaginärteil.
Ich habe jetzt mal hier ein Bilderalbum angelegt, weil dieses "ins Leere Gerede" ohne Bild glaube ich nichts nützt. Hier mal die ffts:
http://www.funpic.de/fotos/philipphtoner/1/80397gruß Philipp
-
PhilippHToner schrieb:
Nöö, also ich rede hier nur C++ Code, den ich halt mathematisch dargestellt hab, aber die fft wird ja richtig gefüttert. Komplexes Eingangssignal ohne Imaginärteil.
Ich habe jetzt mal hier ein Bilderalbum angelegt, weil dieses "ins Leere Gerede" ohne Bild glaube ich nichts nützt. Hier mal die ffts:
http://www.funpic.de/fotos/philipphtoner/1/80397gruß Philipp
Und wo fehlen da jetzt die positiven Frequenzen? Ist doch alles in Butter. Oder verstehst Du nicht, wieso der Realteil fehlt? Erzeuge mal das Signal mit cos anstatt sin. Dann fehlt plötzlich Der Imaginärteil. Erzeuge mal ein Signal, und lass die Phase bei w/4 starten. Dann hast Du plätzlich sowohl Re als auch Im.
Und nun guck Dir mal den Transformationskern der DFT an und überlege, wo das her kommt. Außerdem nochmal zum Recherchieren: Was gibt die Beziehung zwischen Re und Im wieder?
-
Ich weiß nicht, was die Beziehung zwischen Re und Im wiedergibt. Ich dachte, der Im-Teil gibt die Phase an, wo der sin startet, deshalb verstehe ich nicht, wieso ein stinknormaler sin( w(i) * f + 0.0*π) ohne Phase in der Spektralansicht bei Im=0.5 hat.
-
PhilippHToner schrieb:
Ich weiß nicht, was die Beziehung zwischen Re und Im wiedergibt. Ich dachte, der Im-Teil gibt die Phase an, wo der sin startet, deshalb verstehe ich nicht, wieso ein stinknormaler sin( w(i) * f + 0.0*π) ohne Phase in der Spektralansicht bei Im=0.5 hat.
Die DFT ist eine reversible Transformation. Das heisst, alle Infos, welche Du im Zeitbereich hast, müssen sich auch im Frequenzbereich irgendwo verstecken.
Im Zeitbereich hast Du Amplitude, Frequenz und Phase. Im Frequenzbereich hast Du direkt Sichtbar erstmal nur Frequenz und Amplitude. Aber irgendwo muss sich auch noch die Phaseninformation verstecken. Sonst könnest Du keine volständige phasenkorrekte Rücktransformation machen (solche Sachen wie Overlap-Add/Safe wären dann nicht möglich). Die Phaseninformation steckt also Im Verhätnis von Re und Im (die Phaseninformation kann man in der komplexen Ebene daher auch sehr schön am Winkel ablesen).
-
Okay, ich glaub ich hab es jetzt soweit gecheckt. Ich brauch lediglich die Polarform der komplexen Zahlen. Das einzige, was mich verwirrt hat, war, dass durch den Winkel jetzt das Fließkommazahlen-Flimmern zum Vorschein kommt, weil sowas wie atan2(Im, Re) dann interessante Werte geben. Aber ich sollte das glaub ich nicht hernehmen, weil atan2(0.0, 0.0) eigentlich schon wieder nicht mehr definiert ist.
-
xmf schrieb:
Ich habe folgendes vor:
Mithilfe des Fourierspektrums möchte ich bestimmte Effekte in eienr graphsichen Anwendung auslösen.
Die Effekte sollen durch bestimmte Ton-Frequenzen getriggert werden
z.b. bei Bässen verwischt das Bild und bei hohen Tönen tritt eine Rotation ein.
Wie kann ich aus dem Fourier-Spektrum ablesen, was hohe und tiefe Töne sind?
Jenseits davon, dass Du Dir natürlich frequenzabhängige Schwellwerte suchen kannst, solltest Du glaube ich generell mit Wavelets arbeiten, um so das zeitliche Auftreten der jeweiligen Frequenzen am besten bestimmen zu können.
-
schau dir diesen beispiel an: http://www.codeproject.com/Articles/14873/Simple-Audio-Out-Oscilloscope-and-Spectrum-Analyze