Synchronous/Asynchrnous Audio play with pymedia

R

Ron Provost

Hello,

I'm developing a piece of software to assist illiteraate adults to learn to
read. I'm trying to figure out how, if possible, to make audio playback
asynchrnous but still controllable. I'm using python 2.4 with pymedia on
XP. I started out with the example in the tutorials section of the pymedia
website. The pymedia docs imply to me that playback using Output's play()
method should already be asynchronous and controllable. I judge this
because of the presence of the pause() and unpause() methods. However, when
I run the example I find that play() in fact is not returning until an
entire frame has been played through the sound card. This isn't entirely a
problem since the frames are small, but I would prefer to give the entire
sound file to the class and let it go on playing while I continue with other
processing. If, at some point during playback, I wish to pause, unpause or
completely stop playback, I would like, again, to be able to make
asynchronous calls to do so. Doe anybody know if this is possible? Am I
using pymedia incorrectly?

I've attempted to construct a threaded class to handle my problem, but I'm a
novice with threads and It's not working properly. To use this class, first
make an instance. To assign an mp3 file for playback use myInst.select(
myFileObj ). To begin playback or to unpause use: myInst.play( ). to
pause use: myInst.pause( ). to stop use: myInst.stop( ). Once stopped,
myInst.play( ) should restart playback from the beginning. The problem is
that when I stop(), restarting with play() doesn't work. Instead, the
thread silently terminates.

Thanks for any help you can offer. I've been trying to solve this on my own
for days now and just know it shouldn't be this hard.




import time
import pymedia.audio.sound as sound
import pymedia.audio.acodec as acodec
import threading, Queue

class AudioPlayer( threading.Thread ):
# States
PLAY = 1
PAUSE = 2
STOP = 3

def __init__( self ):
threading.Thread.__init__( self )

self.setDaemon( 1 )
self.requestQueue = Queue.Queue( )
self.start( )

def select( self, filelikeObj ):
self.requestQueue.put( filelikeObj )

def play( self ):
self.requestQueue.put( AudioPlayer.PLAY )

def pause( self ):
self.requestQueue.put( AudioPlayer.PAUSE )

def stop( self ):
self.requestQueue.put( AudioPlayer.STOP )

def run( self ):
state = AudioPlayer.STOP
file = None
snd = None

while True:
if (state == AudioPlayer.PLAY) and self.requestQueue.empty( ):
if not snd:
cparams= { 'id': acodec.getCodecID( 'mp3' ) }
codec = acodec.Decoder( cparams )
file.seek( 0 )
bytes = file.read( 8192 )
frame = codec.decode( bytes )
snd = sound.Output( frame.sample_rate, frame.channels,
sound.AFMT_S16_LE )
else:
bytes = file.read( 512 )
if len(bytes) > 0:
frame = codec.decode( bytes )

if frame:
snd.play( frame.data )
else:
if snd:
snd.stop( )
snd = None
state = AudioPlayer.STOP
else:
msg = self.requestQueue.get( )

if msg in ( AudioPlayer.PAUSE, AudioPlayer.PLAY ):
state = msg
else:
if snd:
snd.stop( )
snd = None
state = AudioPlayer.STOP
if msg != AudioPlayer.STOP:
file = msg

# Test application
if __name__ == '__main__':
import time
player = AudioPlayer( )
snd = open( 'music.mp3', 'rb' )
player.select( snd )
player.play( )
time.sleep( 3 )

player.pause( )
time.sleep( 3 )
player.play( )
time.sleep( 10 )
player.stop( )
time.sleep( 3 )
player.play( )
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top