Sun audio blocks, even when run in a thread

Chris Liechti cliechti at gmx.net
Mon Dec 1 16:17:16 EST 2003


[posted and mailed]

Bruce.Bon at SubaruTelescope.org (Bruce Bon) wrote in 
news:184d1516.0311281857.4f6a8a8a at posting.google.com:

> The class below is intended to play a Sun audio file (.au) in the
> background while the main thread, which is servicing a GUI, continues
> without impact.  It doesn't work.  For a sound file that takes 3-5
> seconds to play, the main thread hangs for that long.  I have run this
> many times, with changes in printouts and insertion of strategic
> sleeps to try to make sure that the player thread gives up control,
> but apparently the call to audioObj.write( audioString ) is atomic --
> NOTHING happens in the  main thread until it returns.  I have tested
> this with print statements and sleeps in the main thread instead of a
> GUI, and you can see the program's output simply halt while the sound
> is audible.  I have also looked for delays at dataLock.acquire() and
> not found any.
> 
> Help, suggestions, explanation or work-around??

no sorry, not for your problem directly...
_if_ there is a bug in the python module. it maybe, if the sunaudiodev is 
implemented in C and forgets to release the GIL during the io operation.
altough i doubt it somehow, bugs in python itself are rare....

but, i can comment on your code ;-)

look at the module "Queue" that would save you the lock and all its 
problems if you doo it manualy. it has also a get() function that can 
block, so you dont need your poll loop with a sleep.

if you insist on using locks, consider try: ... finally: clasues, with 
lock.release() in the finally block, so that you dont produce a deadlock, 
even on exceptions.

i always use the "threading" module. its much cleaner in my option. i have 
seen you tried it too :-)

chris

> import time
> import sunaudiodev
> from thread import *
> 
> class AudioPlayer:
> 
>     def __init__( self, owner ):
>         '''Constructor.'''
>         self.soundQueue = []
>         self.terminateFlag = False
>         self.dataLock = allocate_lock()
>         print 'AudioPlayer:  starting playerThread...'
>         print '              main thread ID = ', get_ident()
>         self.playerThread = start_new_thread( self.__playerThread, ()
> )
>         
> 
>     def playAudio( self, audio ):
>         self.dataLock.acquire()
>         self.soundQueue.append( audio ) # put to end of list
>         self.dataLock.release()
> 
>     def terminate( self ):
>         self.dataLock.acquire()
>         self.terminateFlag = True
>         self.dataLock.release()
>         time.sleep(1)
> 
>     def __playerThread( self ):
>         '''Function to be executed in background thread, to play
> sounds.'''
>         print '__playerThread() starting: ID = ', get_ident()
>         while True:    
>             # Check terminateFlag and soundQueue
>             audio = None
>             self.dataLock.acquire()
>             if self.terminateFlag:
>                 self.dataLock.release()
>                 print '__playerThread(): terminating playerThread...'
>                 exit()
>             l = len(self.soundQueue)
>             if  l > 0:
>                 audio = self.soundQueue.pop(0)  # get from beginning
> of list
>             self.dataLock.release()
> 
>             if  audio == None:
>                 time.sleep( 1.0 )               # poll queue 1/second
>             else:
>                 # Read the .au file
>                 auReadObj = open( audio, 'r' )
>                 audioString = auReadObj.read()
>                 auReadObj.close()
> 
>                 # Open the audio device and play the sound
>                 try:
>                     audioObj = sunaudiodev.open('w')
>                 except sunaudiodev.error:
>                     print 'ERROR __playerThread:  ' + \
>                                 'Failed to open Sun audio device.'
>                 else:
>                     audioObj.write( audioString )
>                     audioObj.close()



-- 
Chris <cliechti at gmx.net>





More information about the Python-list mailing list