Conversion de Fourier du fichier wav lu par Python, conversion inverse et réécriture

Bonjour tous le monde

Soudain, j'ai commencé à jouer avec python et c'est la troisième fois, mais cette fois je jouerai également avec le fichier wav. Cette fois, nous allons effectuer une transformée de Fourier sur les données de forme d'onde lues par wav, ou les restaurer par transformée de Fourier inverse et l'écrire dans wav.

Conversion de Fourier

Sonique

Le son est généré par la vibration de l'air (son). En outre, la vibration est constituée de vibrations superposées de fréquences multiples. Parmi ces vibrations sonores, la fréquence dominante détermine la hauteur, la magnitude de l'amplitude détermine le volume du son et les vibrations de diverses fréquences non dominantes déterminent la tonalité du son.

Conversion de Fourier

Comme le son contient différentes fréquences, il est difficile de l'analyser tel quel. Par conséquent, une méthode a été inventée pour exprimer le son par une simple superposition. C'est l'expansion de la classe Fourier.

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

C'est comme ça. Je ne parlerai pas de mathématiques ici, donc si vous ne le comprenez pas, vous voudrez peut-être le rechercher dans la formule d'Euler. Maintenant, si vous connaissez $ a_k $ ici, vous pouvez approximer ce $ f (t) $. Comment devriez-vous le trouver? Utilisons une petite astuce, mais supposons d'abord que vous observiez $ f (t) $ pendant un certain temps, $ T $. Multipliez les deux côtés de l'expansion de la série précédente par $ e ^ {- \ rm {i} k't} $ et essayez d'intégrer.

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

Ce sera. Si vous sélectionnez $ k $ comme $ 2n \ pi / T $ ici, l'intégration sur le côté droit ne restera que lorsque $ k = k '$.

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

Ce calcul pour trouver $ a_k $ s'appelle la transformation de Fourier. En réalité, cette intégrale est approchée par calcul numérique.

Conversion inverse de Fourier

Une fois que vous avez $ a_k $, l'expansion de la classe de Fourier est terminée. La génération de la forme d'une fonction d'espace réel à partir de la distribution de $ a_k $ est appelée transformation inverse de Fourier.

Convertir le fichier wav en fourier

Eh bien, mettons de côté l'histoire théorique et effectuons le traitement proprement dit. Identique à la dernière fois Utilisez jupyter. Tout d'abord, lisez le fichier wav comme d'habitude.

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('Canal', ch)
print('Nombre total d'images', fn)
print('Temps d'échantillonnage', 1.0 * N * span / fr, 'Secondes')

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

print('Longueur actuelle du tableau', len(origin))
print('Exemple de longueur de séquence: ', len(data))

Quand tu fais ça,

Canal 2
Nombre total de vues 15884224
Temps d'échantillonnage 87.07482993197279 secondes
Longueur actuelle du tableau 63536896
Exemple de longueur de séquence:  15360000

Le résultat est comme ça. La raison pour laquelle la longueur du tableau «d'origine» de lecture est quatre fois le nombre de trames semble être parce qu'une trame fait 4 octets parce qu'elle est stéréo et que la taille de l'échantillon est de 2 (16 bits). ʻOrigin` est une chaîne d'octets, donc c'est naturel. .. ..

Pour le moment, traitons les données extraites afin qu'elles puissent être facilement converties en Fourier.

#Hypothèse stéréo
X = np.frombuffer(data, dtype="int16")
left = X[::2]
right = X[1::2]

Tout d'abord, lisez les exemples de données avec int16 et divisez-les en le son entendu de la gauche et le son entendu de la droite.

Ensuite, définissez la conversion de Fourier et la conversion inverse (expansion de classe). Cette fois, nous utiliserons numpy fft. fft est une bibliothèque pour 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

La fonction «fourier» renvoie un tableau de distributions de fréquences pour chaque intervalle d'échantillonnage. La fonction ʻinverse_fourier` génère une forme d'onde dans l'espace réel basée sur la distribution de fréquence.

Cette fois, je ne ferai aucun traitement spécial, je convertis simplement la conversion de Fourier immédiatement et la conversion inverse et l'écrirai en wav.

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='-')

Commençons par le convertir en Fourier. Ensuite, la distribution de fréquence pour chaque section d'échantillon peut être obtenue. Si vous tracez la distribution à un moment approprié, vous obtiendrez le résultat suivant. スクリーンショット 2017-06-08 0.10.34.png

Après avoir confirmé que la distribution de fréquence est correcte, effectuons une conversion inverse.

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)

C'est un peu gênant, mais comme il s'agit d'une source sonore stéréo, le Fourier inverse de la source sonore gauche et le Fourier inverse de la source sonore droite sont mélangés.

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

Alors, je vais l'écrire.

J'ai fait quelque chose qui ne semble pas contre nature, même pour moi-même sans entendre.

Résumé

J'ai converti le contenu du fichier wav en Fourier et joué avec. Pour le moment, c'est comme ça cette fois.

référence

numpy.fft

Recommended Posts

Conversion de Fourier du fichier wav lu par Python, conversion inverse et réécriture
Lisez le fichier ligne par ligne avec Python
Lisez le fichier ligne par ligne avec Python
Lisez le fichier csv et affichez-le dans le navigateur
Lisez le fichier xml en vous référant au didacticiel Python
Lire le fichier json avec Python, le formater et générer le json
Lire et écrire un fichier csv
Lire et écrire des fichiers
Écrire et lire des fichiers
Lisez le fichier csv avec le notebook jupyter et écrivez le graphique l'un sur l'autre
Comment changer le fichier de configuration pour qu'il soit lu par Python
[Python] Utilisez ceci pour lire et écrire des fichiers wav [wavio]
[PEP8] Reprenez le code source Python et écrivez-le proprement
Lire la feuille Excel et le processus en boucle ligne par ligne Python VBA
Traitez le fichier gzip UNLOADed avec Redshift avec Python de Lambda, gzipez-le à nouveau et téléchargez-le sur S3
Lisez l'ancien fichier Word du formulaire d'application Gakushin DC (.doc) à partir de Python et essayez de le faire fonctionner
[Python Kivy] Comment obtenir le chemin du fichier par glisser-déposer
Lisons le fichier RINEX avec Python ①
Ecrire le fichier O_SYNC en C et Python
Lisez le fichier en spécifiant le code de caractère.
Lire et écrire des fichiers JSON avec Python
Lisez le fichier avec python et supprimez les sauts de ligne [Notes sur la lecture du fichier]
Lisez le fichier CSV avec Python et convertissez-le en DataFrame tel quel
[python] Lisez le fichier html et entraînez-vous au scraping
[Python] Lire la ligne spécifiée dans le fichier
[Python] Précautions lors de l'acquisition de données en grattant et en les mettant dans la liste
Python --Lisez les données d'un fichier de données numériques et recherchez la ligne de régression multiple.
[Python] Combiner des listes contenant des nombres en chaînes et les écrire dans un fichier de sortie
[Python3] Lecture et écriture avec isoformat datetime avec json
Écrivons un programme Python et exécutons-le
Lire ligne par ligne à partir d'un fichier avec Python
Je veux remplacer les variables dans le fichier de modèle python et le produire en masse dans un autre fichier
Modèle de script python pour lire le contenu du fichier
Expérience de comparaison de la vitesse d'écriture de fichier entre python 2.7.9 et pypy 2.5.0
[Python] One-liner FFT (transformation de Fourier rapide) et autres folies
Lire et écrire en virgule flottante simple précision en Python
Lire et écrire des fichiers avec Slackbot ~ Développement de bot avec Python ~
Le VIF calculé par Python et le VIF calculé par Excel sont différents .. ??
Lire et écrire des balises NFC avec python en utilisant PaSoRi
Python --Lisez des données à partir d'un fichier de données numériques pour trouver des matrices, des valeurs propres et des vecteurs propres distribués co-distribués
Obtenez de manière récursive la liste Excel dans un dossier spécifique avec python et écrivez-la dans Excel.
[Apprentissage automatique] Ecrivez vous-même la méthode k-plus proche voisin en python et reconnaissez les nombres manuscrits.
Lire le fichier csv Python
[Python] Ouvrez le fichier csv dans le dossier spécifié par pandas
Obtenez le type MIME en Python et déterminez le format de fichier
[Python] J'ai installé le jeu depuis pip et j'ai essayé de jouer
Le processus de création et d'amélioration du code Python orienté objet
Lisez le fichier VTK et affichez la carte des couleurs avec jupyter.
Je pensais ne pas avoir vu le fichier pyc récemment, mais il a été isolé dans pycache par python3