Salutations

Voilà, dans le cadre d'un projet scolaire, je dois, à partir d'un fichier wav contenant un son pur (c'est à dire une seule note avec une fréquence bien définie), retrouver cette sus-dite fréquence.

(En vrai, mon fichier wav contient plusieurs notes, mais je me charge de découper mon wav en n=nombre de notes fichiers, et je les anaylse un par un)

Voici donc mon code, j'utilise la transformée de Fourier :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
frequences = []
#Ouverture du fichier wav à décrypter
wav_original = wave.open("sons/elpkzgyldd.wav",'rb')
(nchannels, sampwidth, framerate, nframes, comptype, compname) = wav_original.getparams()
 
#Ensuite, il va découper le fichier wav en n=nombre de notes fichiers
nbr_notes = nframes/2500
 
for i in range(0, nbr_notes):
    debut = int(i*2500)
    fin = int((i*2500)+2500)
 
    wav_original.setpos(debut)
    print wav_original.tell()
    donnee_partie = wav_original.readframes(int((fin-debut)*framerate))
 
    partie_fichier_son = wave.open('dcrpt_fichier.wav','wb')
    partie_fichier_son.setnchannels(nchannels)
    partie_fichier_son.setsampwidth(sampwidth)
    partie_fichier_son.setframerate(framerate)
    partie_fichier_son.writeframes(donnee_partie)
    partie_fichier_son.close()
 
    #Maintenant, on applique la transformée de Fourier
    wav = wave.open("dcrpt_fichier.wav",'rb')
    (nchannels, sampwidth, framerate, nframes, comptype, compname) = wav.getparams()
    frames = wav.readframes(nframes)
 
    data = struct.unpack('%sh' % (nframes * nchannels), frames)
 
    w = np.fft.fft(data)
    freqs = np.fft.fftfreq(len(w))
    idx=np.argmax(np.abs(w)**2)
    freq=freqs[idx]
    frequence=abs(freq*framerate)
 
    #On arrondit la fréquence, car elle est non-entière
    partie_decimale = frequence-int(frequence)
    if(partie_decimale >= 0.5):
        frequence=int(frequence+0.5)
    else:
        frequence=int(frequence-0.5)
 
    frequences.append(frequence)
    wav.close()
    os.remove("dcrpt_fichier.wav")
print frequences
Voici ce que me retourne cet algorithme :
[247, 182, 247, 182, 248, 182, 248]

Or il est censé me retourner :
[247, 182, 248, 182, 249, 182, 250]

D'accord on est pas très loin, mais il me faut les fréquences exactes

Et parfois, les écarts sont éléphantesques ! Par exemple je dois obtenir ceci :
[266, 264, 255, 265, 266, 247, 260, 262, 255, 249, 267, 266]

Et mon algorithme retourne :
[267, 265, 265, 267, 267, 266, 266, 266, 266, 266, 267, 267]

Ventre-saint-gris ! me direz-vous, que fait donc cette transformée de Fourier ?
Existe-t-il un moyen d'obtenir les fréquences exactes ? Je ne tiens point forcément à utiliser la transformée de Fourier, car comme dans le cochon, tout est bon pour que je parvienne à mes fins !

En vous remerciant d'avance de l'intérêt que vous porterez à mon problème !