Wave-Datei-Analyse via FFT



Ähnliche Dokumente
Primzahlen und RSA-Verschlüsselung

Würfelt man dabei je genau 10 - mal eine 1, 2, 3, 4, 5 und 6, so beträgt die Anzahl. der verschiedenen Reihenfolgen, in denen man dies tun kann, 60!.

Einführung in die Programmierung

Bildverarbeitung Herbstsemester Fourier-Transformation

13. Lineare DGL höherer Ordnung. Eine DGL heißt von n-ter Ordnung, wenn Ableitungen y, y, y,... bis zur n-ten Ableitung y (n) darin vorkommen.

Grundlagen der höheren Mathematik Einige Hinweise zum Lösen von Gleichungen

Welche Lagen können zwei Geraden (im Raum) zueinander haben? Welche Lagen kann eine Gerade bezüglich einer Ebene im Raum einnehmen?

Technik der Fourier-Transformation

Fourier-Zerlegung, Fourier-Synthese

Informationsblatt Induktionsbeweis

Objektorientierte Programmierung

Einführung in die Java- Programmierung

7 Rechnen mit Polynomen

Aufgaben Leiten Sie die Formeln (9) und (10) her! Vorbetrachtungen. Der High-Fall

Im Jahr t = 0 hat eine Stadt Einwohner. Nach 15 Jahren hat sich die Einwohnerzahl verdoppelt. z(t) = at + b

Zählen von Objekten einer bestimmten Klasse

Wir machen neue Politik für Baden-Württemberg

1 Mathematische Grundlagen

Kontrollstrukturen und Funktionen in C

Physik & Musik. Stimmgabeln. 1 Auftrag

Lineare Differentialgleichungen erster Ordnung erkennen

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

OECD Programme for International Student Assessment PISA Lösungen der Beispielaufgaben aus dem Mathematiktest. Deutschland

Anleitung zur Erstellung von Serienbriefen (Word 2003) unter Berücksichtigung von Titeln (wie Dr., Dr. med. usw.)

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Grundlagen der Theoretischen Informatik, SoSe 2008

Lineare Gleichungssysteme

Überblick. Lineares Suchen

1 topologisches Sortieren

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Das Briefträgerproblem

Vermessung und Verständnis von FFT Bildern

Abiturprüfung Mathematik 2008 (Baden-Württemberg) Berufliche Gymnasien ohne TG Analysis, Aufgabe 1

Anleitung über den Umgang mit Schildern

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom b

Gleichungen Lösen. Ein graphischer Blick auf Gleichungen

MATLAB Kurs 2010 Teil 2 Eine Einführung in die Frequenzanalyse via MATLAB

Programmierkurs Java

Die Gleichung A x = a hat für A 0 die eindeutig bestimmte Lösung. Für A=0 und a 0 existiert keine Lösung.

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Lineare Gleichungssysteme

Musterlösung 2. Mikroprozessor & Eingebettete Systeme 1

Java Kurs für Anfänger Einheit 5 Methoden

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

= {} +{} = {} Widerstand Kondensator Induktivität

Handbuch. NAFI Online-Spezial. Kunden- / Datenverwaltung. 1. Auflage. (Stand: )

Modellierung und Programmierung 1

Informationssysteme Gleitkommazahlen nach dem IEEE-Standard 754. Berechnung von Gleitkommazahlen aus Dezimalzahlen. HSLU T&A Informatik HS10

HIER GEHT ES UM IHR GUTES GELD ZINSRECHNUNG IM UNTERNEHMEN

Grundlagen der Videotechnik. Redundanz

Einführung in die Algebra

DIFFERENTIALGLEICHUNGEN

Algorithmen & Datenstrukturen 1. Klausur

C++ Tutorial: Timer 1

Konzepte der Informatik

Elektrische Messtechnik Protokoll - Bestimmung des Frequenzgangs durch eine Messung im Zeitbereich

Informatik Grundlagen, WS04, Seminar 13

Abschlussprüfung Realschule Bayern II / III: 2009 Haupttermin B 1.0 B 1.1

Abituraufgabe zur Analysis, Hessen 2009, Grundkurs (TR)

Musterlösungen zur Linearen Algebra II Blatt 5

Professionelle Seminare im Bereich MS-Office

Messtechnik-Praktikum. Spektrumanalyse. Silvio Fuchs & Simon Stützer. c) Berechnen Sie mit FFT (z.b. ORIGIN) das entsprechende Frequenzspektrum.

Lichtbrechung an Linsen

Übung Grundlagen der Programmierung. Übung 05: Arrays. Abgabetermin: xx.xx.xxxx. Java-Programm Testplan Testergebnisse

Kapitel MK:IV. IV. Modellieren mit Constraints

Historical Viewer. zu ETC5000 Benutzerhandbuch 312/15

Mathematischer Vorbereitungskurs für Ökonomen

4. BEZIEHUNGEN ZWISCHEN TABELLEN

Operationalisierbare Qualitätskriterien für die Programmierung mit Erfahrungen aus PRÜ1 und PRÜ2

Satzhilfen Publisher Seite Einrichten

FDAX mit Zertifikaten gehandelt

R ist freie Software und kann von der Website.

Programmieren in C. Rekursive Funktionen. Prof. Dr. Nikolaus Wulff

Studentische Lösung zum Übungsblatt Nr. 7

11.3 Komplexe Potenzreihen und weitere komplexe Funktionen

1 Vom Problem zum Programm

Korrelation (II) Korrelation und Kausalität

Binäre Gleitkommazahlen

Info zum Zusammenhang von Auflösung und Genauigkeit

Einführung in die Programmierung (EPR)

Approximation durch Taylorpolynome

Prozentrechnung. Wir können nun eine Formel für die Berechnung des Prozentwertes aufstellen:

Abituraufgabe zur Stochastik, Hessen 2009, Grundkurs (TR)

Unterrichtsmaterialien in digitaler und in gedruckter Form. Auszug aus: Übungsbuch für den Grundkurs mit Tipps und Lösungen: Analysis

Behörde für Bildung und Sport Abitur 2008 Lehrermaterialien zum Leistungskurs Mathematik

Die reellen Lösungen der kubischen Gleichung

Zahlenwinkel: Forscherkarte 1. alleine. Zahlenwinkel: Forschertipp 1

1 C H R I S T O P H D R Ö S S E R D E R M A T H E M A T I K V E R F Ü H R E R

A Lösungen zu Einführungsaufgaben zu QueueTraffic

In vergleichsbasierten Suchbäumen wird nicht in Schlüssel hineingeschaut.

Diana Lange. Generative Gestaltung Operatoren

7.3 Einrichtung 13. Monatslohn. Auszahlung Ende Jahr / Ende der Beschäftigung

Physik 4, Übung 11, Prof. Förster

Datenexport aus JS - Software

Praktikum zu Einführung in die Informatik für LogWiIngs und WiMas Wintersemester 2015/16. Vorbereitende Aufgaben

Musterlösung zu Serie 14

NODELOCKED LIZENZ generieren (ab ST4)

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Transkript:

Wave-Datei-Analyse via FFT Wave-Dateien enthalten gesampelte Daten, die in bestimmten Zeitabständen gespeichert wurden. Eine Fourier-Transformation über diesen Daten verrät das Frequenz-Spektrum der zugrunde liegenden Wellen. Dies kann man effektiv über Fast Fourier Transformation (FFT) algorithmisieren...

Überblick Vorüberlegungen Fourier-Transformation Fast Fourier Transformation und Algorithmen Wave-Datei-Analyse

Vorüberlegungen Werte zwischen -128 und 127 (8-bit) bzw. -32768 und 32767 (16-bit) Konstante Abstände zwischen den einzelnen Werten 1 t= SamplingRate Endliche Anzahl von Daten, jedoch in großen Mengen, vorhanden

Fourier-Transformation

Fourier-Transformation Jede mögliche Schwingung auf einer Periode T läßt sich als unendliche Summe von Sinus- und Kosinus-Funktionen darstellen: Das Wichtigste ist es nun, die Koeffizienten A k und B k zu berechnen. f t = k=0 mit k = 2 k T und B 0 =0 A k cos k t B k sin k t

Fourier-Koeffizienten Dies geht, wie man durch arithmetische Operationen zeigen kann, so: A k = 2 T /2 T T /2 B k = 2 T /2 T T /2 f t cos k t dt für k 0 T /2 A 0 = 1 T T /2 f t dt f t sin k t dt für alle k

Umwandlung in komplexe Schreibweise Die Eulersche Identität läßt uns Sinus und Kosinus auch im komplexen Fall fassen: e i t =cos t isin t Wir können nun unser f(t) komplex auffassen: mit k = 2 k T f t =A 0 k= C k e i k t und C 0=A 0,C k = A k i B k 2,C k = A k i B k 2 Natürlich lassen sich dann auch die Koeffizienten C k komplex formulieren: C k = 1 T /2 T T /2 f t e i k t dt für k

Diskrete Fourier-Transformation Die bisher betrachteten Formeln beziehen sich auf kontinuierliche Funktionen. Hier haben wir jedoch nur Stichproben, unsere Samples {f k }. Umformuliert lautet die Formel für das Spektrum {F j } also so: N 1 F j = 1 N k =0 f k W N k j 2 i N mit W N =e

Fast Fourier Transformation und Algorithmen

Laufzeit Fourier-Transformation Würde man diese Formel direkt in einen Algorithmus umformulieren, würde man feststellen, dass er eine Laufzeit von O(N 2 ) hat (für jedes j müssen wir N k's durchlaufen). Daten Laufzeit 256 65536 512 262144 1024 1048576 2048 4194304

Laufzeit Fast Fourier Transformation Durch geschickte Überlegungen (dass man aus zwei Fourier-Reihen eine machen kann, und dass bei einer Fourier-Reihe der Länge 1 F 0 =f 0 ist) kann man einen Algorithmus der Laufzeit O(N log 2 N) schreiben. Daten Laufzeit 256 2048 512 4608 1024 10240 2048 22528

Algorithmus public static void four1(double data[], int nn, int isign) Der Algorithmus selbst besteht aus zwei Teilen, der erste sortiert die Daten neu für den Algorithmus und der zweite berechnet die Fourier-Transformationen. Die Daten werden wie folgt an den Algorithmus übergeben: f 0 f 0 f 1 f 1 f 2 f 2... f N-2 f N-2 f N-1 f N-1 1 2 3 4 5 6... 2N-3 2N-2 2N-1 2N f 0 ist der reelle Teil und f 0 der imaginäre Teil der komplexen Zahl f 0. nn ist N, isign=1 bedeutet FFT, isign=-1 inverse FFT.

public static void four1(double data[], int nn, int isign) { int n, mmax, m, j, istep, i; double wtemp, wr, wpr, wpi, wi, theta; // Double precision for the // trigonometric recurrences. double tempr, tempi; n = nn << 1; j = 1; for (i = 1; i < n; i += 2) { if (j > i) { double temp = data[j]; data[j] = data[i]; data[i] = temp; temp = data[j+1]; data[j+1] = data[i+1]; data[i+1] = temp; } // if m = n >> 1; while (m >= 2 && j > m) { j -= m; m >>= 1; } // while j += m; } // for // This is the bit-reversal section // of the routine. // Exchange the two complex numbers.

public static void four1(double data[], int nn, int isign) { // Here begins the Danielson-Lanczos section of the routine. mmax = 2; while (n > mmax) { // Outer loop executed log2 nn times. istep = mmax << 1; // Initialize the trigonometric recurrence. theta = isign * (2.0 * Math.PI/mmax); wtemp = Math.sin(0.5*theta); wpr = -2.0 * wtemp * wtemp; wpi = Math.sin(theta); wr = 1.0; wi = 0.0; for (m = 1; m < mmax; m += 2) { // Here are the two nested inner loops. for (i = m; i <= n; i += istep) { j = i + mmax; // This is the Danielson-Lanczos // formula: tempr = wr * data[j] - wi * data[j + 1]; tempi = wr * data[j + 1] + wi * data[j]; data[j] = data[i] tempr; data[j + 1] = data[i + 1] - tempi; data[i] += tempr; data[i + 1] += tempi; } // for // Trigonometic recurrence. wr = (wtemp = wr) * wpr - wi * wpi + wr; wi = wi * wpr + wtemp * wpi + wi; } // for mmax = istep; } // while } // four1(float data[], long nn, int isign)

four1(): Output-Daten Die Daten werden in folgendem Format wieder zurückgegeben: f=0 f=0 f=1/n f=1/n... f=(n/2-1)/n f=(n/2-1)/n 1 2 3 4... N-1 N f=±1/2 f=±1/2 f=-(n/2-1)/n f=-(n/2-1)/n N+1 N+2 N+3 N+4... 2N-1 2N... f=-1/n f=-1/n f 0 ist der reelle Teil und f 0 der imaginäre Teil der komplexen Zahl f 0.

Komfortable Methoden complexfft() und complexfftinv() übernehmen die Bestimmung von N und reorganisieren das [0..2N-1]- Datenfeld in ein [1..2N]-Datenfeld und zurück: public static void complexfft(double data[]) { if (ispowerof2(data.length)) { double[] d = new double[data.length + 1]; d[0] = 0.0; // copy the array for (int i = 0; i < data.length; i++) { d[i + 1] = data[i]; } // for // call the fast fourier transformation algorithm four1(d, (d.length - 1) / 2, 1); // copy the array back for (int i = 1; i < d.length; i++) { data[i - 1] = d[i]; } // for } // if else throw new IllegalArgumentException("The passed array does not have " + "the length of a Power of 2."); } // complexfft(double data[])

Reelle Fast Fourier Transformation Eine reelle Fast Fourier Transformation ist nichts anderes als eine komplexe Fast Fourier Transformation, wo alle imaginären Teile der f n =0. Es gilt: F n =F N-n * (komplex konjugiert). Deshalb braucht nur das positive Frequenzspektrum gespeichert zu werden. Es ist möglich, zwei reelle FFT in dem Algorithmus für komplexe FFT gleichzeitig durchzuführen (twofft()).

Komfortable Methode public static void realfft(double data[]) Input: f 0 f 1... f N-1 f N 0 1... N-2 N-1 Output (f=0 und f=±1/(2 ) haben keinen imaginären Teil): f=0 f=±1/(2 ) f=1/(n ) f=1/(n )... 0 1 2 3...... f=(n/2-1)/(n ) f=(n/2-1)/(n )... N-2 N-1 f 0 ist der reelle Teil und f 0 der imaginäre Teil der komplexen Zahl f 0.

Wave-Datei-Analyse

Format der Daten Die Daten eines Audio-Kanals liegen in einem int[] data sortiert nach ihrem zeitlichen Auftreten vor. Zu jedem int[] data gibt es eine Sample-Rate float samplingrate. Sie bezeichnet die Anzahl der Samples pro Sekunde. Die Werte der einzelnen ints liegen zwischen -128 und 127 (8-bit) bzw. -32768 und 32767 (16-bit).

Analyse der FFT-Daten Wichtig sind die absoluten Größen der Intensitäten (also der komplexen Zahlen). Diese errechnen sich durch folgende Formel: z = R z 2 I z 2 Die Frequenzen zu den dazugehörigen Intensitäten können durch die schon öfters erwähnte Formel errechnet werden: F i = i N 1 mit = SamplingRate

analysewavedata(): Ein Stück Wave-Daten analysieren Der folgende Algorithmus transportiert einen Teil der Wave- Daten in den realfft()-algorithmus und gibt die Analyse zurück. Zuerst Kopf und Parameter-Check: public static double[][] analysewavedata(int[] data, int start, int end, float samplingrate) { // what can happen... if (start >= end) throw new IllegalArgumentException("\"start\" must be higher then " + "\"end\"."); if (!FastFourierTransformation.isPowerOf2(end - start)) throw new IllegalArgumentException("Can only analyse data with the " + "length of a Power of 2."); if (data == null) throw new IllegalArgumentException("I need some data to analyse."); if (end > data.length) throw new IllegalArgumentException("\"data\" is too small.");

public static double[][] analysewavedata(int[] data, int start, int end, float samplingrate) { // copy the data into a new array int N = end - start; double[] d = new double[n]; for (int i = start, j = 0; i < end; i++, j++) { d[j] = data[i]; } // for // Fast Fourier Transformation does the wave file analysis FastFourierTransformation.realFFT(d); double[][] output = new double[n / 2 + 1][2]; // get out F[N/2] output[n / 2][0] = samplingrate / 2.0; output[n / 2][1] = Math.abs(d[1]); d[1]=0.0; // get out F[0]..F[N/2-1] for (int i = 0; i < d.length / 2; i++) { output[i][0] = (double)i * samplingrate / N; output[i][1] = Math.sqrt(d[i * 2] * d[i * 2] + d[i * 2 + 1] * d[i * 2 + 1]); } // for return output; } // analysewavedata(int[] data, int start, int end, int samplingrate)

analysewavedata(): Output- Daten Zurückgegeben wird ein zweidimensionales Array von Doubles double[][], das für jede errechnete Intensität bei einer bestimmten Frequenz ein Pärchen bereithält, das die Frequenz und die Intensität beinhaltet: double[i][0]=frequenz double[i][1]=intensität bei Frequenz Die Anzahl der Pärchen ist genau end start +1 (also immer eine Potenz von 2+1).

analysewavefile(): einen Teil einer Wave-Datei analysieren Nun haben wir fast alles, um eine echte Wave-Datei zu analysieren. Was nun noch fehlt sind ein paar Routinen, die die Daten aus einer Wave-Datei holen und an analysewavedata() schicken. Dabei kommt die schon bekannte Klasse AudioData mit ins Spiel: AudioData AudioData(java.io.File audiofile) int[] getleftchannel() int[] getrightchannel() float getsamplerate()

analysewavefile(): einen Teil einer Wave-Datei analysieren Der Rest ist nun trivial: public static double[][] analysewavefile(string fname, double start_sec, int lengthfft, boolean leftchannel) { AudioData d = new AudioData(new File(fname)); int start = (int)(start_sec * d.getsamplerate()); if (leftchannel) return analysewavedata(d.getleftchannel(), start, start + lengthfft, d.getsamplerate()); else return analysewavedata(d.getrightchannel(), start, start + lengthfft, d.getsamplerate()); } // analysewavefile(string fname, double start_sec, int lengthfft, // boolean leftchannel) Die Output-Daten sind die, die von analysewavedata() zurückgegeben werden.

showanalysiswindow(): die Daten auf den Bildschirm bringen Die Daten sind nun soweit, dass sie visuell dargestellt werden können. Da es hier um die Analyse der Daten geht und nicht um java.awt.*. Deshalb nur das Wichtigste. Für die Darstellung ist eine logarithmische Skala der Y- Achse praktisch. Somit wird die Lautstärke linear in db dargestellt. Hinzu kommt noch die Normalisierung, die hier jedoch ohne weitere Bedeutung ist. // logarithmic plot of data gets a better graph for (int i = 0; i < d.length; i++) { d[i][1] = Math.log(d[i][1] / (double)fft_length); } // for x :log x c =log x log c Das Objekt FrequencyWindow ist ein Fenster, das die Daten plottet. Der wichtigste Teil dabei ist die Methode paint(), die die eigentliche Arbeit übernimmt.

Literatur Tilman Butz: Fouriertransformation für Fußgänger, Stuttgart, Leipzig, 2000. Numerical Recipes Software: NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING, Cambridge, 1992, http://www.nr.com/. Sun Microsystems: Java 2 SDK, Standard Edition Documentation Version 1.3.1, http://java.sun.com/j2se/1.3/docs.html. Materialien zur Sitzung: http://www.t-online.de/~datzko/musik/wissenschaft/fft.zip.