web-dev-qa-db-fra.com

comment lire un fichier wav en python?

J'ai essayé pygame pour lire un fichier wav comme ceci:

import pygame
pygame.init()

pygame.mixer.music.load("mysound.wav")
pygame.mixer.music.play()
pygame.event.wait()

mais ça change la voix et je ne sais pas pourquoi! J'ai lu ce lien des solutions et ne peux pas résoudre mon problème avec la lecture du fichier wave!

pour cette solution, je ne sais pas quoi dois-je importer?

s = Sound() 
s.read('sound.wav') 
s.play()

et pour cette solution/dev/dsp n'existe pas dans la nouvelle version de linux:

from wave import open as waveOpen
from ossaudiodev import open as ossOpen
s = waveOpen('tada.wav','rb')
(nc,sw,fr,nf,comptype, compname) = s.getparams( )
dsp = ossOpen('/dev/dsp','w')
try:
  from ossaudiodev import AFMT_S16_NE
except ImportError:
  if byteorder == "little":
    AFMT_S16_NE = ossaudiodev.AFMT_S16_LE
  else:
    AFMT_S16_NE = ossaudiodev.AFMT_S16_BE
dsp.setparameters(AFMT_S16_NE, nc, fr)
data = s.readframes(nf)
s.close()
dsp.write(data)
dsp.close()

et quand j'ai essayé pyglet ça me donne cette erreur:

import pyglet

music = pyglet.resource.media('mysound.wav')
music.play()

pyglet.app.run()
--------------------------

nima@ca005 Desktop]$ python play.py
Traceback (most recent call last):
  File "play.py", line 4, in <module>
    music = pyglet.resource.media('mysound.wav')
  File "/usr/lib/python2.7/site-packages/pyglet/resource.py", line 587, in media
    return media.load(path, streaming=streaming)
  File "/usr/lib/python2.7/site-packages/pyglet/media/__init__.py", line 1386, in load
    source = _source_class(filename, file)
  File "/usr/lib/python2.7/site-packages/pyglet/media/riff.py", line 194, in __init__
    format = wave_form.get_format_chunk()
  File "/usr/lib/python2.7/site-packages/pyglet/media/riff.py", line 174, in get_format_chunk
    for chunk in self.get_chunks():
  File "/usr/lib/python2.7/site-packages/pyglet/media/riff.py", line 110, in get_chunks
    chunk = cls(self.file, name, length, offset)
  File "/usr/lib/python2.7/site-packages/pyglet/media/riff.py", line 155, in __init__
    raise RIFFFormatException('Size of format chunk is incorrect.')
pyglet.media.riff.RIFFFormatException: Size of format chunk is incorrect.
AL lib: ReleaseALC: 1 device not closed
22
nim4n

Vous pouvez utiliser PyAudio . Un exemple ici sur mon Linux ça marche:

#!usr/bin/env python  
#coding=utf-8  

import pyaudio  
import wave  

#define stream chunk   
chunk = 1024  

#open a wav format music  
f = wave.open(r"/usr/share/sounds/alsa/Rear_Center.wav","rb")  
#instantiate PyAudio  
p = pyaudio.PyAudio()  
#open stream  
stream = p.open(format = p.get_format_from_width(f.getsampwidth()),  
                channels = f.getnchannels(),  
                rate = f.getframerate(),  
                output = True)  
#read data  
data = f.readframes(chunk)  

#play stream  
while data:  
    stream.write(data)  
    data = f.readframes(chunk)  

#stop stream  
stream.stop_stream()  
stream.close()  

#close PyAudio  
p.terminate()  
33
zhangyangyu

La raison pour laquelle Pygame modifie votre audio est que la table de mixage par défaut est une fréquence d'échantillonnage de 22k:

initialize the mixer module
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=4096): return None

Votre wav est probablement 8k. Ainsi, lorsque pygame le joue, il joue environ deux fois plus vite. Spécifiez donc votre fréquence wav dans l'init.

Pyglet a quelques problèmes pour lire correctement les en-têtes RIFF. Si vous avez un fichier wav très basique (avec exactement un bloc fmt de 16 octets) sans aucune autre information dans le bloc fmt (comme les données "factuelles"), cela fonctionne. Mais il ne prévoit pas de données supplémentaires dans les morceaux, donc il ne respecte vraiment pas la spécification d'interface RIFF.

7
Gene