By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,494 Members | 1,079 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,494 IT Pros & Developers. It's quick & easy.

Sun audio blocks, even when run in a thread

P: n/a
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??

Thanks.

Bruce Bon

_______________________________

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()
Jul 18 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
I converted this module to using threading instead of thread -- same behavior.
Jul 18 '05 #2

P: n/a
[posted and mailed]

Br*******@SubaruTelescope.org (Bruce Bon) wrote in
news:18**************************@posting.google.c om:
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 <cl******@gmx.net>

Jul 18 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.