spatialaudio / python-sounddevice

:sound: Play and Record Sound with Python :snake:
https://python-sounddevice.readthedocs.io/
MIT License
980 stars 145 forks source link

RawOutputStream occasionally plays on random output #427

Closed QuadCorei8085 closed 1 year ago

QuadCorei8085 commented 1 year ago

Running on windows10 (python 3.9.7) calling the RawOutputStream with a device I would like to play a buffer/file most of the time works but occasionally the stream is palyed on the notebook's speaker without an error or exception happening.

I call query_devices -> find my device and use the index of the device (number between 0-35) that I pass to RawOutputStream as device=N.

Sometimes it works and plays the stream on the device, sometimes it plays the sound on the notebook's speaker, even though the windows default is a totally different output (a USB headset).

Any way to debug what is going on?

QuadCorei8085 commented 1 year ago

While playing around I found that query_devices is listing the device names with wrong ID IF the library is loaded and I unplug / replug the USB microphone/speaker. For some strange reason in this case the running python script and other programs won't correctly map the audio streams. In such case also audacity is playing the sound on the notebook speaker when switched to USB speaker and vice-versa.

However when i issue a "python -m sounddevice" in commandline the list gets updated and then the observed ID/names are shown correctly (at least I see that the selected ID corresponds to the wrongly used output device).

For some reason the loaded library (dll?) won't update properly when the USB device is unplugged/replugged.

I already tried "importlib.reload(sd)" but didn't help.

Anyone having similar issues? Any ideas how to resolve this? Any workaround is welcomed.

mgeier commented 1 year ago

Changing devices (plugging/unplugging) is currently not supported by the underlying PortAudio library.

See #125, #343, #382 for more details.

QuadCorei8085 commented 1 year ago

Seems like this is exactly what I've been looking for.

Duplicate of #125

Thanks, this workaround is more than acceptable for me. sd._terminate() sd._initialize()