J'ai besoin d'analyser le son écrit dans un fichier .wav. Pour cela, j'ai besoin de transformer ce fichier en ensemble de nombres (tableaux, par exemple). Je pense que j'ai besoin d'utiliser le package wave. Cependant, je ne sais pas comment cela fonctionne exactement. Par exemple, j'ai fait ce qui suit:
import wave
w = wave.open('/usr/share/sounds/ekiga/voicemail.wav', 'r')
for i in range(w.getnframes()):
frame = w.readframes(i)
print frame
À la suite de ce code, je m'attendais à voir la pression acoustique en fonction du temps. En revanche, je vois beaucoup de symboles étranges et mystérieux (qui ne sont pas des nombres hexadécimaux). Quelqu'un peut-il, s'il vous plaît, m'aider avec ça?
data
est une matrice de numpy 2-D de sortedata.shape
retourne un tuple de (num_samples, num_channels)En utilisant le
struct
module , vous pouvez prendre les trames d'onde (qui sont dans le binaire complémentaire de 2 entre -32768 et 32767 (c'est-à0x8000
- dire et0x7FFF
). Cela lit un fichier MONO, 16-BIT, WAVE. J'ai trouvé cette page Web très utile pour formuler ceci:import wave, struct wavefile = wave.open('sine.wav', 'r') length = wavefile.getnframes() for i in range(0, length): wavedata = wavefile.readframes(1) data = struct.unpack("<h", wavedata) print(int(data[0]))
Cet extrait de code lit 1 image. Pour lire plus d'une image (par exemple, 13), utilisez
wavedata = wavefile.readframes(13) data = struct.unpack("<13h", wavedata)
la source
Différents modules Python pour lire wav:
Il existe au moins ces bibliothèques suivantes pour lire les fichiers audio wave:
L'exemple le plus simple:
Voici un exemple simple avec SoundFile:
import soundfile as sf data, samplerate = sf.read('existing_file.wav')
Format de la sortie:
Attention, les données ne sont pas toujours au même format, cela dépend de la bibliothèque. Par exemple:
from scikits import audiolab from scipy.io import wavfile from sys import argv for filepath in argv[1:]: x, fs, nb_bits = audiolab.wavread(filepath) print('Reading with scikits.audiolab.wavread:', x) fs, x = wavfile.read(filepath) print('Reading with scipy.io.wavfile.read:', x)
Production:
Reading with scikits.audiolab.wavread: [ 0. 0. 0. ..., -0.00097656 -0.00079346 -0.00097656] Reading with scipy.io.wavfile.read: [ 0 0 0 ..., -32 -26 -32]
SoundFile et Audiolab renvoient des flotteurs entre -1 et 1 (comme le fait matab, c'est la convention pour les signaux audio). Scipy et wave renvoient des entiers, que vous pouvez convertir en flottants en fonction du nombre de bits d'encodage, par exemple:
from scipy.io.wavfile import read as wavread samplerate, x = wavread(audiofilename) # x is a numpy array of integers, representing the samples # scale to -1.0 -- 1.0 if x.dtype == 'int16': nb_bits = 16 # -> 16-bit wav files elif x.dtype == 'int32': nb_bits = 32 # -> 32-bit wav files max_nb_bit = float(2 ** (nb_bits - 1)) samples = x / (max_nb_bit + 1) # samples is a numpy array of floats representing the samples
la source
À mon humble avis , le moyen le plus simple d'obtenir des données audio à partir d'un fichier audio dans un tableau NumPy est SoundFile :
import soundfile as sf data, fs = sf.read('/usr/share/sounds/ekiga/voicemail.wav')
Cela prend également en charge les fichiers 24 bits prêts à l'emploi.
Il existe de nombreuses bibliothèques de fichiers audio disponibles, j'ai écrit un aperçu où vous pouvez voir quelques avantages et inconvénients. Il comporte également une page expliquant comment lire un fichier wav 24 bits avec le
wave
module .la source
Vous pouvez accomplir cela en utilisant le scikits.audiolab module . Il nécessite NumPy et SciPy pour fonctionner, ainsi que libsndfile.
Notez que je n'ai pu le faire fonctionner que sur Ubunutu et non sur OSX.
from scikits.audiolab import wavread filename = "testfile.wav" data, sample_frequency,encoding = wavread(filename)
Maintenant vous avez les données wav
la source
scikits.audiolab
n'a pas été mis à jour depuis 2010 et il s'agit probablement de Python 2 uniquement.Si vous souhaitez traiter un bloc audio bloc par bloc, certaines des solutions proposées sont assez horribles dans le sens où elles impliquent de charger tout l'audio en mémoire, produisant de nombreux échecs de cache et ralentissant votre programme. python-wavefile fournit des constructions pythoniques pour effectuer le traitement bloc par bloc NumPy en utilisant une gestion de bloc efficace et transparente au moyen de générateurs. D'autres subtilités pythoniques sont le gestionnaire de contexte pour les fichiers, les métadonnées comme propriétés ... et si vous voulez toute l'interface de fichier, parce que vous développez un prototype rapide et que vous ne vous souciez pas de l'efficacité, toute l'interface de fichier est toujours là.
Un exemple simple de traitement serait:
import sys from wavefile import WaveReader, WaveWriter with WaveReader(sys.argv[1]) as r : with WaveWriter( 'output.wav', channels=r.channels, samplerate=r.samplerate, ) as w : # Just to set the metadata w.metadata.title = r.metadata.title + " II" w.metadata.artist = r.metadata.artist # This is the prodessing loop for data in r.read_iter(size=512) : data[1] *= .8 # lower volume on the second channel w.write(data)
L'exemple réutilise le même bloc pour lire tout le fichier, même dans le cas du dernier bloc qui est généralement inférieur à la taille requise. Dans ce cas, vous obtenez une tranche du bloc. Faites donc confiance à la longueur de bloc retournée au lieu d'utiliser une taille 512 codée en dur pour tout traitement ultérieur.
la source
Si vous souhaitez effectuer des transferts sur les données de forme d'onde, vous devriez peut-être utiliser SciPy , en particulier
scipy.io.wavfile
.la source
J'avais besoin de lire un fichier WAV 24 bits à 1 canal. Le message ci-dessus de Nak était très utile. Cependant, comme mentionné ci-dessus par basj 24 bits n'est pas simple. Je l'ai finalement fait fonctionner en utilisant l'extrait de code suivant:
from scipy.io import wavfile TheFile = 'example24bit1channelFile.wav' [fs, x] = wavfile.read(TheFile) # convert the loaded data into a 24bit signal nx = len(x) ny = nx/3*4 # four 3-byte samples are contained in three int32 words y = np.zeros((ny,), dtype=np.int32) # initialise array # build the data left aligned in order to keep the sign bit operational. # result will be factor 256 too high y[0:ny:4] = ((x[0:nx:3] & 0x000000FF) << 8) | \ ((x[0:nx:3] & 0x0000FF00) << 8) | ((x[0:nx:3] & 0x00FF0000) << 8) y[1:ny:4] = ((x[0:nx:3] & 0xFF000000) >> 16) | \ ((x[1:nx:3] & 0x000000FF) << 16) | ((x[1:nx:3] & 0x0000FF00) << 16) y[2:ny:4] = ((x[1:nx:3] & 0x00FF0000) >> 8) | \ ((x[1:nx:3] & 0xFF000000) >> 8) | ((x[2:nx:3] & 0x000000FF) << 24) y[3:ny:4] = (x[2:nx:3] & 0x0000FF00) | \ (x[2:nx:3] & 0x00FF0000) | (x[2:nx:3] & 0xFF000000) y = y/256 # correct for building 24 bit data left aligned in 32bit words
Une mise à l'échelle supplémentaire est requise si vous avez besoin de résultats compris entre -1 et +1. Peut-être que certains d'entre vous pourraient trouver cela utile
la source
s'il ne s'agit que de deux fichiers et que la fréquence d'échantillonnage est significativement élevée, vous pouvez simplement les entrelacer.
from scipy.io import wavfile rate1,dat1 = wavfile.read(File1) rate2,dat2 = wavfile.read(File2) if len(dat2) > len(dat1):#swap shortest temp = dat2 dat2 = dat1 dat1 = temp output = dat1 for i in range(len(dat2)/2): output[i*2]=dat2[i*2] wavfile.write(OUTPUT,rate,dat)
la source
Vous pouvez également utiliser une
import wavio
bibliothèque simple. Vous devez également avoir des connaissances de base sur le son.la source
PyDub ( http://pydub.com/ ) n'a pas été mentionné et cela devrait être corrigé. IMO, c'est la bibliothèque la plus complète pour la lecture de fichiers audio en Python à l'heure actuelle, mais pas sans ses défauts. Lire un fichier wav:
from pydub import AudioSegment audio_file = AudioSegment.from_wav('path_to.wav') # or audio_file = AudioSegment.from_file('path_to.wav') # do whatever you want with the audio, change bitrate, export, convert, read info, etc. # Check out the API docs http://pydub.com/
PS. L'exemple concerne la lecture d'un fichier wav, mais PyDub peut gérer de nombreux formats différents prêts à l'emploi. La mise en garde est qu'il est basé à la fois sur le support natif de Python wav et ffmpeg, vous devez donc avoir ffmpeg installé et beaucoup de capacités pydub reposent sur la version ffmpeg. Habituellement, si ffmpeg peut le faire, pydub peut aussi le faire (qui est assez puissant).
Non-avertissement: je ne suis pas lié au projet, mais je suis un gros utilisateur.
la source