I believe I've somehow managed to create some kind race condition in either sounddevice
or my script that's causing a hard crash of python without throwing any exceptions or errors. Looking for some help to figure out what's going wrong.
The following is a basic version of what I'm doing in the script. Essentially it's taking audio samples in the form of a comma-separated string from a websocket
, converting them to a numpy float32
array, adding them to a queue
, and then letting a sounddevice OutputStream
callback pull from this queue to play to the speakers. See the code below.
handleMicData
is called from that websocket's handler function every time new audio data is received from the connected client. Since that handler function is an async
function, I think that's possibly where the issue with timing is arising. There's also many other things happening in several created threads related to messaging and serving data, but none of them touch anything related to the data I'm working with here.
import sounddevice as sdimport numpy as npmicSampleQueue = queue.Queue()audioStream = sd.OutputStream(samplerate=48000, channels=1, callback=outputCallback, blocksize=512, dtype=np.float32)audioStream.start()def outputCallback(outdata, frames, time, status): # print the device status if there is one if status: print(status) # only get samples if we've got a good buffer built up if micSampleQueue.qsize() > 2: print("outputCallback()") samples = micSampleQueue.get_nowait() outdata[:,0] = samples else: outdata.fill(0)def handleMicData(dataString): print("handleMicData()") # Split into a list of strings stringList = dataString.split(",") # Remove empty strings stringList[:] = [item for item in stringList if item] # Convert string list to floats floatArray = np.asarray(stringList, dtype=np.float32) # put the data to the queue micSampleQueue.put_nowait(floatArray)
The above code will crash after an inconsistent period of time. Sometimes I'll be able to get audio for 10 seconds, and sometimes the first couple data messages are enough to crash it. Below is an example of what the console output looks like after a crash.
handleMicData()handleMicData()outputCallback()outputCallback()outputCallback()handleMicData()handleMicData()handleMicData()outputCallback()outputCallback()outputCallback()handleMicData()handleMicData()handleMicData()outputCallback()outputCallback()outputCallback()handleMicData()handleMicData()handleMicData()handleMicData()outputCallback()outputCallback()outputCallback()handleMicData()handleMicData()outputCallback()outputCallback()outputCallback()handleMicData()handleMicData()handleMicData()outputCallback()outputCallback()outputCallback()handleMicData()handleMicData()handleMicData()outputCallback()outputCallback()outputCallback()handleMicData()handleMicData()handleMicData()outputCallback()outputCallback()outputCallback()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()handleMicData()(python-radio-console) PS H:\Documents\GitHub\python-radio-console>
Notice how now errors or exceptions are being thrown. It appears that the outputCallback function stops getting called at some point and the script crashes silently to the terminal shortly after. Also notice how occasionally the two function prints happen on the same line. That's another indicator, to me at least, that something funny is going on with timing in this script.
I have no clue how I'd even begin debugging this. I've scoured through my code and there isn't anywhere I'm suppressing an exception with except Exception
(I do catch some specific exceptions but nowhere in the audio code). Any suggestions are greatly appreciated!
Edit/Update
I replaced sounddevice
with pyAudio
in my code, and the issue does not occur. Perfect audio with no crashes so far. Long-term I'd like to figure out sounddevice, since it's a better library with more support, but for now pyAudio will do.