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
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:
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:
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()
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()
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')
.
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()