Thursday, March 3, 2011

Play a Sound with Python

What's the easiest way to play a sound file (.wav) in Python? By easiest I mean both most platform independent and requiring the least dependencies. pygame is certainly an option, but it seems overkill for just sound.

From stackoverflow
  • pyMedia's sound example does just that. This should be all you need.

    import time, wave, pymedia.audio.sound as sound
    f= wave.open( 'YOUR FILE NAME', 'rb' )
    sampleRate= f.getframerate()
    channels= f.getnchannels()
    format= sound.AFMT_S16_LE
    snd= sound.Output( sampleRate, channels, format )
    s= f.readframes( 300000 )
    snd.play( s )
    
    Claudiu : hehe, that works fine, but the snack example takes much less lines of code! i'm sure pymedia is more flexible
  • The Snack Sound Toolkit can play wav, au and mp3 files.

    s = Sound() 
    s.read('sound.wav') 
    s.play()
    
  • Definitely use Pyglet for this. It's kind of a large package, but it is pure python with no extension modules. That will definitely be the easiest for deployment. It's also got great format and codec support.

    import pyglet
    
    music = pyglet.resource.media('music.mp3')
    music.play()
    
    pyglet.app.run()
    
    Steen : only one problem with this example: the media file needs to be on the (python-) path
  • For Windows, you can use winsound. It's built in

    import winsound, sys
    
    def beep(sound):
        winsound.PlaySound('%s.wav' % sound, winsound.SND_FILENAME)
    
    if __name__ == '__main__':
        beep(sys.argv[1])
    

    You should be able to use ossaudiodev for 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()
    

    (Credit for ossaudiodev: Bill Dandreta http://mail.python.org/pipermail/python-list/2004-October/288905.html)

    Claudiu : this is good - it seems easy to build a wrapper that would at least work for these two platforms
    Jeffrey Aylesworth : Avoid oss, it's old. I don't think I even have it installed anymore.
  • I like pygame, and the command below should work:

    pygame.init()
    pygame.mixer.Sound('sound.wav').play()
    

    but it doesn't on either of my computers, and there is limited help on the subject out there. edit: I figured out why the pygame sound isn't working for me, it's not loading most sounds correctly, the 'length' attribute is ~0.0002 when I load them. maybe loading them using something other than mygame will get it morking more generally.

    with pyglet I'm getting a resource not found error Using the above example, wigh both relative and full paths to the files.

    using pyglet.media.load() instead of pyglet.resource.media() lets me load the files.

    but sound.play() only plays the first fraction of a second of the file, unless I run pyglet.app.run() which blocks everything else...

  • wxPython has support for playing wav files on Windows and Unix - I am not sure if this includes Macs. However it only support wav files as far as I can tell - it does not support other common formats such as mp3 or ogg.

0 comments:

Post a Comment