Fourier-Konvertierung der von Python gelesenen WAV-Datei, umgekehrte Konvertierung und erneutes Schreiben

Hallo zusammen

Plötzlich habe ich angefangen mit Python zu spielen und dies ist das dritte Mal, aber dieses Mal werde ich auch mit der WAV-Datei spielen. Dieses Mal führen wir eine Fourier-Konvertierung der von wav gelesenen Wellenformdaten durch oder stellen sie durch inverse Fourier-Konvertierung wieder her und schreiben sie in wav.

Fourier-Umwandlung

Schall

Schall wird durch die Schwingung von Luft (Schall) erzeugt. Darüber hinaus besteht die Schwingung aus überlappenden Schwingungen mehrerer Frequenzen. Unter solchen Schallschwingungen bestimmt die dominante Frequenz die Tonhöhe, die Größe der Amplitude bestimmt die Lautstärke des Schalls und die Schwingungen verschiedener nicht dominanter Frequenzen bestimmen den Ton des Schalls.

Fourier-Umwandlung

Da der Ton verschiedene Frequenzen enthält, ist es schwierig, ihn so zu analysieren, wie er ist. Daher wurde ein Verfahren erfunden, um den Klang durch eine einfache Überlagerung auszudrücken. Dies ist die Erweiterung der Fourier-Klasse.

f(t) = \sum_k a_k e^{\rm{i}kt}, \ \ \ \ \ e^{\rm{i}kt} = \cos(kt) + \rm{i}\sin(kt)

Es ist so. Ich werde hier nicht über Mathematik sprechen. Wenn Sie es also nicht verstehen, möchten Sie es vielleicht in Eulers Formel nachschlagen. Wenn Sie hier $ a_k $ kennen, können Sie dieses $ f (t) $ approximieren. Wie sollten Sie das finden? Verwenden wir einen kleinen Trick, aber nehmen wir zunächst an, Sie beobachten $ f (t) $ für eine bestimmte Zeit, $ T $. Multiplizieren Sie beide Seiten der vorherigen Serienerweiterung mit $ e ^ {- \ rm {i} k't} $ und versuchen Sie zu integrieren.

\int_0^T f(t)e^{-\rm{i}k't}dt = \sum_k a_k \int_0^T e^{\rm ikt - ik't}dt

Es wird sein. Wenn Sie hier $ k $ als $ 2n \ pi / T $ auswählen, bleibt die Integration auf der rechten Seite nur erhalten, wenn $ k = k '$.

a_k = \frac{1}{T} \int_0^T f(t)e^{-\rm ikt}dt

Diese Berechnung zum Finden von $ a_k $ wird als Fourier-Transformation bezeichnet. In der Realität wird dieses Integral durch numerische Berechnung angenähert.

Inverse Fourier-Umwandlung

Sobald Sie $ a_k $ haben, ist die Erweiterung der Fourier-Klasse abgeschlossen. Das Erzeugen der Form einer Realraumfunktion aus der Verteilung von $ a_k $ wird als Fourier-Inverse-Transformation bezeichnet.

Fourier-Konvertierung von WAV-Dateien

Lassen Sie uns die theoretische Geschichte beiseite legen und die eigentliche Verarbeitung durchführen. Wie beim letzten Mal Verwenden Sie Jupyter. Lesen Sie zuerst die WAV-Datei wie gewohnt.

import wave
import struct
from scipy import fromstring, int16
import numpy as np
from pylab import *
%matplotlib inline

wavfile = '/data/input/test.wav'
wr = wave.open(wavfile, "rb")
ch = wr.getnchannels()
width = wr.getsampwidth()
fr = wr.getframerate()
fn = wr.getnframes()

N = 256
span = 15000

print('Kanal', ch)
print('Gesamtzahl der Frames', fn)
print('Beispielzeit', 1.0 * N * span / fr, 'Sekunden')

origin = wr.readframes(wr.getnframes())
data = origin[:N * span * ch * width]
wr.close()

print('Aktuelle Arraylänge', len(origin))
print('Länge der Probensequenz: ', len(data))

Wenn Sie dies tun,

Kanal 2
Gesamtzahl der Frames 15884224
Abtastzeit 87.07482993197279 Sekunden
Aktuelle Array-Länge 63536896
Länge der Probensequenz:  15360000

Das Ergebnis ist so. Der Grund, warum die Länge des gelesenen "Ursprungs" -Arrays das Vierfache der Anzahl von Frames beträgt, scheint darin zu liegen, dass ein Frame 4 Bytes groß ist, weil es Stereo ist und die Abtastgröße 2 (16 Bit) beträgt. Es ist natürlich, weil "Ursprung" eine Byte-Zeichenfolge ist. .. ..

Lassen Sie uns vorerst die extrahierten Daten so verarbeiten, dass sie leicht in Fourier konvertiert werden können.

#Stereo-Annahme
X = np.frombuffer(data, dtype="int16")
left = X[::2]
right = X[1::2]

Lesen Sie zuerst die Beispieldaten mit int16 und teilen Sie sie in den von links zu hörenden und den von rechts zu hörenden Ton auf.

Definieren Sie als Nächstes die Fourier-Konvertierung und die inverse Konvertierung (Klassenerweiterung). Dieses Mal werden wir numpy fft verwenden. fft ist eine Bibliothek für FFT (Fast Discrete Fourier Transform).

def fourier (x, n, w):
    K = []
    for i in range(0, w-2):
        sample = x[i * n:( i + 1) * n]
        partial = np.fft.fft(sample)
        K.append(partial)
        
    return K

def inverse_fourier (k):
    ret = []
    for sample in k:
        inv = np.fft.ifft(sample)
        ret.extend(inv.real)
        
    print (len(sample))
    return ret

Die Funktion "Fourier" gibt für jedes Abtastintervall ein Array von Häufigkeitsverteilungen zurück. Die Funktion "inverse_fourier" erzeugt eine Wellenform im realen Raum basierend auf der Häufigkeitsverteilung.

Dieses Mal werde ich keine spezielle Verarbeitung durchführen, sondern nur die Fourier-Konvertierung sofort konvertieren und die Konvertierung rückgängig machen und in wav schreiben.

Kl = fourier(left, N, span)
Kr = fourier(right, N, span)
freqlist = np.fft.fftfreq(N, d=1/fr)
amp = [np.sqrt(c.real ** 2 + c.imag ** 2) for c in Kl[2500]]
plot(freqlist, amp, marker= 'o', linestyle='-')
axis([0, fr / 2 , 0, 100000])

amp = [np.sqrt(c.real ** 2 + c.imag ** 2) for c in Kr[2500]]
plot(freqlist, amp, marker= 'o', linestyle='-')

Lassen Sie es uns zunächst in Fourier konvertieren. Dann kann die Häufigkeitsverteilung für jeden Probenabschnitt erhalten werden. Wenn Sie die Verteilung zu einem geeigneten Zeitpunkt zeichnen, erhalten Sie das folgende Ergebnis. スクリーンショット 2017-06-08 0.10.34.png

Nachdem Sie bestätigt haben, dass die Häufigkeitsverteilung korrekt ist, führen wir eine inverse Konvertierung durch.

def combine_wav (left, right):
    ret = []
    number = len(right) if len(left) > len(right) else len(left)
    for i in range(0, number -1):
        data = [int(left[i]), int(right[i])]
        ret.extend(data)
        
    return ret

left_dash = inverse_fourier(Kl)
right_dash = inverse_fourier(Kr)
raw_data = combine_wav(left_dash, right_dash)

outd = struct.pack("h" * len(raw_data), *raw_data)

Es ist ein wenig nervig, aber da es sich um eine Stereo-Tonquelle handelt, werden der umgekehrte Fourier der linken Tonquelle und der umgekehrte Fourier der rechten Tonquelle gemischt.

#Export
outf = '/data/output/test.wav'
ww = wave.open(outf, 'w')
ww.setnchannels(ch)
ww.setsampwidth(width)
ww.setframerate(fr)
ww.writeframes(outd)
ww.close()

Also werde ich es aufschreiben.

Ich habe etwas gemacht, das sich selbst für mich selbst ohne Gehör nicht unnatürlich anfühlt.

Zusammenfassung

Ich habe den Inhalt der WAV-Datei in Fourier konvertiert und damit gespielt. Diesmal ist es vorerst so.

Referenz

numpy.fft

Recommended Posts

Fourier-Konvertierung der von Python gelesenen WAV-Datei, umgekehrte Konvertierung und erneutes Schreiben
Lesen Sie die Datei Zeile für Zeile mit Python
Lesen Sie die Datei Zeile für Zeile mit Python
Lesen Sie die CSV-Datei und zeigen Sie sie im Browser an
Lesen Sie die XML-Datei anhand des Python-Tutorials
Lesen Sie die json-Datei mit Python, formatieren Sie sie und geben Sie json aus
CSV-Datei lesen und schreiben
Dateien lesen und schreiben
Dateien schreiben und lesen
Lesen Sie die CSV-Datei mit dem Jupiter-Notizbuch und schreiben Sie die Grafik übereinander
So wechseln Sie die Konfigurationsdatei, die von Python gelesen werden soll
[Python] Verwenden Sie diese Option, um WAV-Dateien zu lesen und zu schreiben. [WAVIO]
[PEP8] Übernehmen Sie den Python-Quellcode und schreiben Sie ihn ordentlich
Lesen Sie die Excel-Tabelle und wiederholen Sie den Prozess zeilenweise Python VBA
Verarbeiten Sie die mit Redshift entladene gzip-Datei mit Python of Lambda, gzipen Sie sie erneut und laden Sie sie in S3 hoch
Lesen Sie das alte Gakushin DC-Antragsformular Word-Datei (.doc) von Python und versuchen Sie, es zu bedienen
[Python Kivy] So erhalten Sie den Dateipfad durch Ziehen und Ablegen
Lesen wir die RINEX-Datei mit Python ①
Schreiben Sie die O_SYNC-Datei in C und Python
Lesen Sie die Datei, indem Sie den Zeichencode angeben.
Lesen und schreiben Sie JSON-Dateien mit Python
Lesen Sie die Datei mit Python und löschen Sie die Zeilenumbrüche [Hinweise zum Lesen der Datei]
Lesen Sie die CSV-Datei mit Python und konvertieren Sie sie unverändert in DataFrame
[Python] Lesen Sie die HTML-Datei und üben Sie das Scraping
[Python] Lesen Sie die angegebene Zeile in der Datei
[Python] Vorsichtsmaßnahmen beim Erfassen von Daten durch Scraping und Einfügen in die Liste
Python - Lesen Sie Daten aus einer numerischen Datendatei und suchen Sie die multiple Regressionslinie.
[Python] Kombinieren von Listen mit Zahlen zu Zeichenfolgen und Schreiben in eine Ausgabedatei
[Python3] Lesen und Schreiben mit datetime isoformat mit json
Schreiben wir ein Python-Programm und führen es aus
Lesen Sie mit Python Zeile für Zeile aus der Datei
Ich möchte die Variablen in der Python-Vorlagendatei ersetzen und in einer anderen Datei in Massenproduktion herstellen
Vorlage des Python-Skripts zum Lesen des Inhalts der Datei
Experiment zum Vergleich der Schreibgeschwindigkeit von Dateien zwischen Python 2.7.9 und Pypy 2.5.0
[Python] Einzeilige FFT (schnelle Fourier-Transformation) und anderer Wahnsinn
Lesen und Schreiben von Gleitkommazahlen mit einfacher Genauigkeit in Python
Lesen und Schreiben von Dateien mit Slackbot ~ Bot-Entwicklung mit Python ~
Das von Python berechnete VIF und das von Excel berechnete VIF sind unterschiedlich.
Lesen und schreiben Sie NFC-Tags mit Python mit PaSoRi
Python - Lesen Sie Daten aus einer numerischen Datendatei, um die verteilte, gemeinsam verteilte Matrix, Eigenwerte und Eigenvektoren zu finden
Rufen Sie die Excel-Liste rekursiv in einem bestimmten Ordner mit Python ab und schreiben Sie sie in Excel.
[Maschinelles Lernen] Schreiben Sie die Methode des nächsten Nachbarn in Python selbst und erkennen Sie handgeschriebene Zahlen.
Lesen Sie die Python-CSV-Datei
[Python] Öffnen Sie die CSV-Datei in dem von Pandas angegebenen Ordner
Holen Sie sich den MIME-Typ in Python und bestimmen Sie das Dateiformat
[Python] Ich habe das Spiel von pip installiert und versucht zu spielen
Der Prozess, Python-Code objektorientiert zu machen und zu verbessern
Lesen Sie die VTK-Datei und zeigen Sie die Farbkarte mit Jupiter an.
Ich dachte, ich hätte die pyc-Datei kürzlich nicht gesehen, aber sie wurde von python3 in pycache isoliert