1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| import wave, struct
from time import sleep
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def func(x,a,b,c):
return c * np.exp( -np.power( (x-a)/b, 2) )
plt.ion() # utilise pyplot en interactif
# Ouverture du fichier wav a decrypter
wav_original = wave.open("son/elpkzgyldd.wav",'rb')
nchannels = wav_original.getnchannels() # Returns number of audio channels (1 for mono, 2 for stereo)
framerate = wav_original.getframerate() # Returns sampling frequency
nframes = wav_original.getnframes() # Returns number of audio frames
# Decouper le fichier en plusieurs parties (une note par partie)
frequences, freq_gauss = [], []
larg_frame = 2500
for posi in range(0,nframes,larg_frame):
# Sequence contenant une note
wav_original.setpos(posi)
donnee = wav_original.readframes(larg_frame)
data = struct.unpack('%sh' % (larg_frame * nchannels), donnee)
# Transformee de Fourier
w = np.fft.fft(data)
sig = np.real(w * w.conjugate())
freqs = np.fft.fftfreq(len(w)) * framerate
# Estimation de la frequence
idx = np.argmax(sig)
f0, maxi = np.abs(freqs[idx]), sig[idx]
frequences.append( f0 )
# Ajustement par une gaussienne
ind = np.where( np.abs(freqs - f0) < 20 )
popt, pcov = curve_fit( func, freqs[ind], sig[ind]/maxi, p0=[f0,1,1] )
a, b, c = popt
freq_gauss.append(a)
# Affichage
plt.plot( freqs[ind], sig[ind], 'o')
fnew = np.linspace( freqs[ind][0], freqs[ind][-1], 512)
plt.plot( fnew, maxi * func(fnew,a,b,c), 'r')
plt.draw() ; sleep(2) ; plt.clf()
wav_original.close()
for res in (frequences,freq_gauss):
print np.round(res, 0)
print "Resultats attendus :\n[247, 182, 248, 182, 249, 182, 250]" |
Partager