web-dev-qa-db-fra.com

Comment tracer un fichier wav

Je viens de lire un fichier wav avec scipy et maintenant je veux faire le tracé du fichier en utilisant matplotlib, sur "l'échelle y", je veux voir l'aplitude et sur "l'échelle x", je veux voir le nombre d'images ! Toute aide, comment puis-je faire ?? Merci!

from scipy.io.wavfile import read
import numpy as np
from numpy import*
import matplotlib.pyplot as plt
a=read("C:/Users/Martinez/Desktop/impulso.wav")
print a
29

Vous pouvez appeler Wave Lib pour lire un fichier audio.

Pour tracer la forme d'onde, utilisez la fonction "plot" de matplotlib

import matplotlib.pyplot as plt
import numpy as np
import wave
import sys


spf = wave.open('wavfile.wav','r')

#Extract Raw Audio from Wav File
signal = spf.readframes(-1)
signal = np.fromstring(signal, 'Int16')


#If Stereo
if spf.getnchannels() == 2:
    print 'Just mono files'
    sys.exit(0)

plt.figure(1)
plt.title('Signal Wave...')
plt.plot(signal)
plt.show()

vous aurez quelque chose comme:enter image description here

Pour tracer l'axe des abscisses en secondes, vous devez obtenir la fréquence d'images et diviser par la taille de votre signal, vous pouvez utiliser la fonction linspace de numpy pour créer un vecteur temporel espacé linéairement avec la taille du fichier audio, puis vous pouvez à nouveau tracer comme plt.plot(Time,signal)

import matplotlib.pyplot as plt
import numpy as np
import wave
import sys


spf = wave.open('Animal_cut.wav','r')

#Extract Raw Audio from Wav File
signal = spf.readframes(-1)
signal = np.fromstring(signal, 'Int16')
fs = spf.getframerate()

#If Stereo
if spf.getnchannels() == 2:
    print 'Just mono files'
    sys.exit(0)


Time=np.linspace(0, len(signal)/fs, num=len(signal))

plt.figure(1)
plt.title('Signal Wave...')
plt.plot(Time,signal)
plt.show()

Nouveau tracé en abscisse en secondes:

enter image description here

49
ederwander

Si vous souhaitez utiliser SciPy, vous pouvez également procéder comme suit:

from scipy.io.wavfile import read
import matplotlib.pyplot as plt

# read audio samples
input_data = read("Sample.wav")
audio = input_data[1]
# plot the first 1024 samples
plt.plot(audio[0:1024])
# label the axes
plt.ylabel("Amplitude")
plt.xlabel("Time")
# set the title  
plt.title("Sample Wav")
# display the plot
plt.show()
16
CuriousCoder

Voici une version qui gérera également les entrées stéréo, basée sur la réponse de @ederwander

import matplotlib.pyplot as plt
import numpy as np
import wave

file = 'test.wav'

with wave.open(file,'r') as wav_file:
    #Extract Raw Audio from Wav File
    signal = wav_file.readframes(-1)
    signal = np.fromstring(signal, 'Int16')

    #Split the data into channels 
    channels = [[] for channel in range(wav_file.getnchannels())]
    for index, datum in enumerate(signal):
        channels[index%len(channels)].append(datum)

    #Get time from indices
    fs = wav_file.getframerate()
    Time=np.linspace(0, len(signal)/len(channels)/fs, num=len(signal)/len(channels))

    #Plot
    plt.figure(1)
    plt.title('Signal Wave...')
    for channel in channels:
        plt.plot(Time,channel)
    plt.show()

 enter image description here

5
Alter

Juste une observation (je ne peux pas ajouter de commentaire).

Vous recevrez le message suivant: 

DeprecationWarning: les codes de type de style numérique sont obsolètes et seront entraîner une erreur dans le futur.

N'utilisez pas np.fromstring avec des fichiers binaires. Au lieu de signal = np.fromstring(signal, 'Int16'), il est préférable d’utiliser signal = np.frombuffer(signal, dtype='int16').

1
Eduardo Freitas

Voici une version qui gère les systèmes mono/stéréo et PCM 8 bits/16 bits.

import matplotlib.pyplot as plt
import numpy as np
import wave

file = 'test.wav'

wav_file = wave.open(file,'r')

#Extract Raw Audio from Wav File
signal = wav_file.readframes(-1)
if wav_file.getsampwidth() == 1:
    signal = np.array(np.frombuffer(signal, dtype='UInt8')-128, dtype='Int8')
Elif wav_file.getsampwidth() == 2:
    signal = np.frombuffer(signal, dtype='Int16')
else:
    raise RuntimeError("Unsupported sample width")

# http://schlameel.com/2017/06/09/interleaving-and-de-interleaving-data-with-python/
deinterleaved = [signal[idx::wav_file.getnchannels()] for idx in range(wav_file.getnchannels())]

#Get time from indices
fs = wav_file.getframerate()
Time=np.linspace(0, len(signal)/wav_file.getnchannels()/fs, num=len(signal)/wav_file.getnchannels())

#Plot
plt.figure(1)
plt.title('Signal Wave...')
for channel in deinterleaved:
    plt.plot(Time,channel)
plt.show()
0
TimSC