Hi, ich verwende momentan einen STM32F4 um über einen externen DAC Audiosignale auszugeben. Das funktioniert problemlos und wie gewünscht. Nach dem ich diese Hard- und Firmware nun schon mal habe, wollte ich mit dem ganzen auch noch ein wenig spielen um selber ein wenig damit zu lernen. Sprich ich stelle mir vor, dieses Audiosignal vor der Ausgabe mit einer Art Klangregler anzupassen (d.h. Höhen, Mitten und Tiefen verändern). So wie ich das sehe, geht das mit einer FFT-Library wie z.B. der von https://stm32f4-discovery.net/2015/07/hal-library-14-fast-fourier-transform-for-stm32fxxx/ Diese Library erzeugt mir aus jeweils einem Teil des Audiosignals ein Array, welches die in dem Signal enthaltenen Frequenzen und deren Amplitude beschreibt. So wie ich das verstehe, müsste ich dieses Array jetzt entsprechend meiner Wünsche anpassen, also die Amplituden der unteren/mittleren/oberen Frequenzen anheben/absenken. Allerdings: wie geht es dann weiter? Wie wandele ich dieses Array wieder in ein Audiosignal um? Oder bin ich hier grundsätzlich auf dem Holzweg und so ein Digitalklangregler ist vollkommen anders zu implementieren?
:
Verschoben durch Admin
Moin, Chris schrieb: > Allerdings: wie geht es dann weiter? Wie wandele ich dieses Array wieder > in ein Audiosignal um? Mittels einer inversen FFT? > Oder bin ich hier grundsätzlich auf dem Holzweg und so ein > Digitalklangregler ist vollkommen anders zu implementieren? Naja, ist nicht ganz ausgeschlossen, dass das mit FFT hin und zurueck irgendwie funktionieren kann, aber mit ein paar Filtern statt der zweifachen Transformiererei wirds sicher mit weniger Rechenbumms gehen. Gruss WK
In der Regel arbeiten die FFT-Routinen mit komplexen Zahlen. Rückwärts geht das nur, wenn du Zugang zum komplexen Ergebnis hast. Wenn das schon in rein reelle Werte umgerechnet ist, dann funzt die iFFT nicht. Gruß
>Oder bin ich hier grundsätzlich auf dem Holzweg und so ein >Digitalklangregler ist vollkommen anders zu implementieren? Holzweg .. eher ja. Einen Klangregler macht man eher über eine Filterbank. Such mal im Netz ...
Bei einer FFT Funktion Library kann man meist sagen ob man FFT oder IFFT macht. Meist gibt es da einen Parameter worüber man das setzt. Aber so einen Parameter sehe ich bei dir nicht. Schade. https://dsp.stackexchange.com/questions/51214/calculate-ifft-using-only-real-forward-fft An hand davon könntest du es per Hand selber implementieren. Aber ich würde an deiner stelle lieber eine andere FFT Lib suchen. #include <math.h> #include "fft.h" #include "c_fft.h" #define SWAP(a,b)tempr=(a);(a)=(b);(b)=tempr float PI = 3.14159265354; static void DanielsonLanzcosRoutine(FftInputType *data, unsigned long cnt, int isign); static void BitReversal(FftInputType *data, unsigned long cnt); void FFT (FftInputType *data, unsigned long cnt) { //the complex array is real + complex so the array //as a size n = 2 * number of complex samples //real part is the data[index] and //the complex part is the data[index+1] BitReversal(data, cnt); DanielsonLanzcosRoutine(data, cnt, 1); } void IFFT (FftInputType *data, unsigned long cnt) { unsigned long i = 0; unsigned long n = cnt; BitReversal(data, cnt); DanielsonLanzcosRoutine(data, cnt, -1); for (i = 0; i < n / 2; i++) { data[i * 2] /= (n / 2); } } void calculateMagnitueAndPhaseFromComplex(FftInputType *data, unsigned long cnt) { unsigned long x = 0; float ampl = 0.0; float fiPI = 0.0; float fiC = 0.0; for (x = 0; x < cnt; x += 2) { ampl = sqrt((pow((float)data[x], 2)) + (pow((float)data[x + 1], 2))); fiPI = tan((float)data[x + 1] / (float)data[x]); fiC = (180.0 * fiPI / (2.0 * PI)); if ((ampl < 0.0001) && (ampl > -0.0001)) { fiC = 0.0; } while (fiC > 360.0) { fiC -= 360.0; } while (fiC < -360.0) { fiC += 360.0; } data[x] = (FftInputType)ampl; data[x + 1] = (FftInputType)fiC ; } } static void BitReversal(FftInputType *data, unsigned long cnt) { //binary inversion (note that the indexes //start from 0 witch means that the //real part of the complex is on the even-indexes //and the complex part is on the odd-indexes unsigned long i = 0; unsigned long j = 0; unsigned long n = cnt; double tempr = 0; for (i = 0; i < n / 2; i += 2) { unsigned long m = 0; if (j > i) { //swap the real part SWAP(data[j], data[i]); //swap the complex part SWAP(data[j + 1], data[i + 1]); // checks if the changes occurs in the first half // and use the mirrored effect on the second half if ((j / 2) < (n / 4)) { //swap the real part SWAP(data[(n - (i + 2))] , data[(n - (j + 2))]); //swap the complex part SWAP(data[(n - (i + 2)) + 1] , data[(n - (j + 2)) + 1]); } } m = n / 2; while (m >= 2 && j >= m) { j -= m; m = m / 2; } j += m; } } static void DanielsonLanzcosRoutine(FftInputType *data, unsigned long cnt, int isign) { unsigned long n = cnt; unsigned long mmax = 0; //Danielson-Lanzcos routine mmax = 2; //external loop while (n > mmax) { double wtemp = 0; double theta = 0; double wi = 0; double wpi = 0; double wr = 0; double wpr = 0; unsigned long m = 0; unsigned long istep = 0; istep = mmax << 1; theta = isign * (2 * PI / mmax); wtemp = sin(0.5 * theta); wpr = -2.0 wtemp wtemp; wpi = sin(theta); wr = 1.0; wi = 0.0; //internal loops for (m = 1; m < mmax; m += 2) { unsigned long i = 0; unsigned long j = 0; for (i = m; i <= n; i += istep) { double tempi = 0; double tempr = 0; j = i + mmax; tempr = wr * (float)data[j - 1] - wi * (float)data[j + 1 - 1]; tempi = wr * (float)data[j + 1 - 1] + wi * (float)data[j - 1]; data[j - 1] = (float)data[i - 1] - tempr; data[j + 1 - 1] = (float)data[i + 1 - 1] - tempi; data[i - 1] += tempr; data[i + 1 - 1] += tempi; } wr = (wtemp = wr) wpr - wi wpi + wr; wi = wi * wpr + wtemp * wpi + wi; } mmax = istep; } }
Franko P. schrieb: > In der Regel arbeiten die FFT-Routinen mit komplexen Zahlen. Rückwärts > geht das nur, wenn du Zugang zum komplexen Ergebnis hast. In der Mechanik zerlegen wir die Schwingungen in einem System auch mittels FFT und verwenden bei der Wiedersynthese nur die Beträge. Der Unterschied ist, dass die Phasen, die ursprünglich im System waren, verloren gehen. Wir erzeugen eigene Phasen, um das System zu steuern. Der herauskommende Signal ist dann anders. Aber: Da beim Audio die Phasen egal sind, weil man sie nicht hören kann, müsste das eigentlich auch egal sein, oder?
Mannfred T. schrieb: > Da beim Audio die Phasen egal sind, weil man sie nicht hören kann Na, zumindest bei Musik sind sie nicht so ganz egal. Stöpsel mal einen deiner Stereolautsprecher um und horche, ob du dann was anderes hörst. ;-)
Das ist aber etwas gänzlich anderes, weil L und R andere Signale bekommen. Die Frage ist doch die: Klingen 50% Sinus (100 Hz * wt) + 50% Sinus (150 Hz * wt) genau so wie 50% Sinus (100 Hz * wt) + 50% Sinus (150 Hz * wt - alpha) Da die beiden Frequenzen schweben, bilden sich ohnehin alle Konstellationen irgendwann einmal - nur zu anderen Zeitpunkten, als im anderen Fall.
Hallo nicht so ganz zu deiner formulierten Frage (oder doch?), aber bezüglich der Überschrift bzw. des Betreffs dann doch passend (und sei es nur für die Mitleser, die wieder besseren Erfahrungen auf eine endliche verständliche Erklärung gehofft haben...) ;-) FFT an sich - wie sie im technischen Zusammenhang entsteht, gebraucht und angewandt wird, ist eigentlich gar nicht so schwer und wird in einigen Videos (und seltener sogar in Texten) eigentlich recht verständlich erklärt. z.B. hier im ersten Teil, der noch ohne Mathematik auskommt: https://www.youtube.com/watch?v=spUNpyF58BY Leider ist aber genau die Mathematik dahinter, dann doch sehr komplex ;-), fern vom Alltagsverständnis und irgendwie schafft es kein Video und auch kein an (relativen) Laien und Hobbyisten wie mir gedachte Text das wirklich so zu erklären, dass man es als interessierter Laie auch mathematisch wirklich nachvollziehen kann und für seine Anwendungen selbst (ohne "magische" fertige Online - Programmanwendungen wo man "nur" die entsprechenden Zahlen für ein ganz bestimmtes Problem eingeben braucht) berechnen kann, bzw. einen klar ist, was man (und wie) dann überhaupt aus den High End Mathe "Baukasten" gebraucht. Obwohl das Wort "komplex" in der Mathematik sicherlich genau genommen wenig mit dem Begriff wie er im Alltag genutzt (gemeint) wird zu tun hat, so passt das "komplex" aus dem Alltag mit dem Sinn "Verwirrend", "verzwickt", "unverständlich" usw. schon ganz gut zusammen... Dergute W. schrieb: > Mittels einer inversen FFT? Das hört sich nach eine schwer verständliches Konzept noch mal eine "Schippe" verwirrender zu machen... (?)
:
Bearbeitet durch User
Bei einem reellen Signal f(t) (ohne irgendwelche Symmetrien) hast Du ein konjugiert-komplexes Specktrum: F*(jw) = F(-jw), also Betrag ist eine gerade Funktion und die Phase ungerade, oder Realteil ist gerade und Imaginärteil ist ungerade. Wenn Du nun im Bildbereich filterst, in dem Du mit einer reellen Filterfunktion multiplizierst, bleibt das resultierende Specktrum konj-komplex und damit ist die Rücktransformierte wieder reell.
Manni T. schrieb: > Da beim Audio die Phasen egal sind, weil man sie nicht hören kann, > müsste das eigentlich auch egal sein, oder? Nein, die Phase ist essentiell. Zerleg mal einen Sägezahn in Frequenzen, setz die Phasen auf Null und gib sie wieder aus. Da kommt eine komplett andere Funktion raus.
Chris schrieb: > Hi, Hi! > Nach dem ich diese Hard- und Firmware nun schon mal habe, wollte ich mit > dem ganzen auch noch ein wenig spielen um selber ein wenig damit zu > lernen. Sprich ich stelle mir vor, dieses Audiosignal vor der Ausgabe > mit einer Art Klangregler anzupassen (d.h. Höhen, Mitten und Tiefen > verändern). Ich habe ein wenig den Eindruck, das Dir ein paar Grundlagen in der Signalbearbeitung fehlen. Das ist kein Problem, jeder fängt mal an. Aber ich würde nicht gleich mit FFT basierten Algorithmen anfangen. Da es erst mal um das Rumprobieren geht, empfehle ich Dir, das Filtern über Biquad Filter zu realisieren. Der mathematische Unterbau davon ist zwar auch nicht ohne, aber es ist viel einfacher erst einmal die Formeln oder fertige Algorithmen zu nehmen und einen Filtereffekt zu erzeugen. Wenn Du mit FFT einsteigst: Auch das ist möglich, allerdings wirst Du Dich zwingend mit so lustigen Dingen wie komplexen Zahlen, Fenster Funktionen, Overlap-and-add Verfahren, negativen Frequenzen usw auseinandersetzen müssen. Ich halte den Lerneffekt, das mit einer FFT mal durchzuziehen für enorm, aber so als erster Versuch, um mit seiner DAC/ADC Schleife auf dem Microcontroller zu spielen, ist es nicht geeignet. Fang daher mal besser mit High- und Lowpass Filtern zweiter Ordnung - implementiert als Biquads an. Das ist für den Anfang schon herausfordernd genug.
Und zum Lernen der Grundlagen gibt es gute Hilfe: https://www.dspguide.com Du kannst das Buch (bzw. alle Kapitel daraus) als PDF runter laden.
Nur eine Kurze Anmerkung: Grundsätzlich muss das mit der inverse-fft funktionieren (wenn auch vlt. nicht in Echtzeit). Es gibt prof. Audio-Software, die einem auf der Y-Achse statt der Amplitude quasi das Ergebnis der FFT darstellt (Y-Achse = Frequenzbänder, Farbe der Pixel analog zur Amplitude des Frequenzbandes in der FFT). Der Clou ist, man kann dann in dieser Grafik fröhlich editieren und somit gezielt Frequenzen eliminieren.
Peter G. schrieb: > Dergute W. schrieb: >> Mittels einer inversen FFT? > > Das hört sich nach eine schwer verständliches Konzept noch mal eine > "Schippe" verwirrender zu machen... (?) Aeeeh - neee. Die FFT und iFFT sind sich nicht so ganz unaehnlich, was die Rechnerei angeht. Das Konzept: FFT, am Ergebnis rumdoktoren, iFFT wird schon verwendet. Ich wuerd's halt nur nicht fuer eine Klangregelung hernehmen. Gunnar F. schrieb: > Zerleg mal einen Sägezahn in Frequenzen, > setz die Phasen auf Null und gib sie wieder aus. Da kommt eine komplett > andere Funktion raus. Das ist unbestritten. Die Frage ist eher: Hoert die sich vielleicht nicht genauso an, wie der original Saegezahn? Problematisch werden dann evtl. Begrenzungseffekte, weil bei unguenstiger Phasenlage der Oberwellen kurze, aber hohe Momentanwerte im Signal auftauchen koennen. Die muss dann der Verstaerker und Lautsprecher erstmal verzerrungsfrei rueberbringen (Und die Cochlea verdauuen). Gruss WK
Dergute W. schrieb: > Aeeeh - neee. Die FFT und iFFT sind sich nicht so ganz unaehnlich, was > die Rechnerei angeht. So isses. Das ist dieselbe Soße mit einem minimalen Unterschied, der allerdings so gut wie keinen Einfluß auf die benötigte Rechenleistung hat. > Das Konzept: FFT, am Ergebnis rumdoktoren, iFFT wird schon verwendet. Und funktioniert tatsächlich auch. > Ich wuerd's halt nur nicht fuer eine Klangregelung hernehmen. Ganz genau. Das ist völlig am Thema vorbei. Das ist die Lösung der Doofen, die nur Wichsvorlagen zusammen bauen können und ihre Unfähigkeit notfalls mit brachialer Rechenleistung erschlagen...
Gunnar F. schrieb: > Nein, die Phase ist essentiell. Zerleg mal einen Sägezahn in Frequenzen, > setz die Phasen auf Null und gib sie wieder aus. Da kommt eine komplett > andere Funktion raus. Sicher. Aber hört das Ohr auch etwas anderes? Die Sinneshaare werden trotzdem genau so angeregt. Die Wellen sind nur gegeneinander zeitversetzt.
Manni T. schrieb: > Sicher. Aber hört das Ohr auch etwas anderes? Die Sinneshaare werden > trotzdem genau so angeregt. Die Wellen sind nur gegeneinander > zeitversetzt. Jein, bei einem konstanten Ton, in moderat gespielter Lautstärke, hört man in der Tat keinen Unterschied. (Wobei: Das kommt wieder auf den Hörer an. Ich kenne Leute, die den Unterschied zwischen einem steigenden und fallenden Sägezahn reproduzierbar wahrnehmen können). Sobald die Lautstärke aber ansteigt, und nicht lineare Effekte in useren Ohren zum Tragen kommen, wird eine Phasenverschiebung hörbar. Insbesondere passiert das in den Transienten. Und noch was, da wir ja über FFT sprechen: Es kommt doch sehr selten vor, das man eine FFT über ein gesammtes Musikstück macht. Dort kann man unter Umständen ohne Phaseninformationen auskommen. In der Praxis macht man die FFT für fast jede Bearbeitung über kleine Teilstücke, bearbeitet dann in der Frequenzebene und wandelt zurück. Verzichtet man hier auf die Phase, so passen die einzenden Blöcke nicht mehr sauber zusammen, und man hört die fehlende bzw. falsche Phase als Störsignal.
Max H. schrieb: > Ich kenne Leute, die den Unterschied zwischen einem steigenden > und fallenden Sägezahn reproduzierbar wahrnehmen können Manche Audiophile können wirklich Erstaunliches wahrnehmen. Soweit das der Fall ist, liegt das aber hauptsächlich an der Übertragung durch die Signalkette und die Lautsprecher. Du bekommst ja keinen perfekten Sägezahn in die Luft, sondern einen gedämpften Anstieg und weiters die durch die geschluckten Anteile des Signals angeregten Schwingungen der Membran. Das ist schon "ab Lautsprecher" etwas anderes, weil das Signal nicht völlig DC liegt und durch die nicht phasenneutrale Signalkette deformiert wird - d.h. die Höhen werden in der Phase stärker verschoben, als die tiefen Anteile und je nach Lage und Anstieg des Signals kommt da dann etwas leicht anderes heraus. Das ist das klassische Verhalten solcher analoger Pfade mit ihrem nicht stabilen DC-Verhalten. Bei einem voll symmetrischen, um Null schwingenden Sägezahn auf hohen Frequenzen spielt das kaum eine Rolle und dann ist das Signal auch gleich dem anderen: Ein idealer Sägezahn, der in X gespiegelt ist, ist nämlich ganz exakt dasselbe wie ein in Y gespiegelter, also z.B. wie bei einem verpolten Lautsprecher. Soweit man ab da noch Unterschiede hört, liegt das definitiv am Lautsprecher, der in die Zugrichtung etwas anders strahlt, als in die Druckrichtung.
Max H. schrieb: > bei einem konstanten Ton Das ist der Punkt. Der Ton ist ja nicht konstant und in den Fällen, in denen die Amplituden und Frequenzen es sind, kommt auch nicht zwangsläufig dasselbe heraus. Grundsätzlich bildet sich zwar in der Tat jede Form der Amplitudenkonstellation, wenn der Ton schwebt, das tut aber nicht jedes Signalkonvolut. Wenn die Frequenzen strikt ganzzahlig passen, ändert sich die Signalform nicht. Die ist statisch und fest durch die Phasen definiert. Nehmen wir den klassischen Fall der 1. und 3. Oberwelle mit jeweils +/-90° Versatz: Im Fall 1 näher sich das Signal einem Dreieck, im anderen Fall einem Rechteck. Noch komplizierter wird es bei 3 oder mehr Frequenzen. Die FFT und iFFT hat aber noch ein anderes Problem: Selbst ausgedehnte FFT über mehrere Perioden des tiefstfrequentesten Signals brauchen eine Fensterung und haben folglich Artefakte. Bei der Resynthese schlagen diese dann als falsche Frequenzanteile zu. D.h. z.B. spiegelt sich eine Frequenz von 200Hz bei einem Blackman-Harris mit Cos2 auch ein wenig in die 400Hz hinein.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.