When using "multiprocessing": Illegal combination of I/O devices [PaErrorCode -9993]
This works fine
def play():
import sounddevice as sd
sd.rec(1024)
play()
However, when I move it into a different process,
from multiprocessing import Process
def play():
import sounddevice as sd
sd.rec(1024)
proc = Process(target=play)
proc.start()
proc.join()
It fails with error -
Process Process-1:
Traceback (most recent call last):
File "/home/dev/.pyenv/versions/3.6.5/lib/python3.6/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/home/dev/.pyenv/versions/3.6.5/lib/python3.6/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "/home/dev/Projects/iwakie/iwakie/sound_effects.py", line 58, in play
sd.rec(1024)
File "/home/dev/.virtualenvs/iwakie-mDP-QX7y/lib/python3.6/site-packages/sounddevice.py", line 223, in rec
ctx.input_dtype, callback, blocking, **kwargs)
File "/home/dev/.virtualenvs/iwakie-mDP-QX7y/lib/python3.6/site-packages/sounddevice.py", line 2416, in start_stream
**kwargs)
File "/home/dev/.virtualenvs/iwakie-mDP-QX7y/lib/python3.6/site-packages/sounddevice.py", line 1300, in __init__
**_remove_self(locals()))
File "/home/dev/.virtualenvs/iwakie-mDP-QX7y/lib/python3.6/site-packages/sounddevice.py", line 779, in __init__
'Error opening {0}'.format(self.__class__.__name__))
File "/home/dev/.virtualenvs/iwakie-mDP-QX7y/lib/python3.6/site-packages/sounddevice.py", line 2571, in _check
raise PortAudioError(errormsg, err)
sounddevice.PortAudioError: Error opening InputStream: Illegal combination of I/O devices [PaErrorCode -9993]
Process finished with exit code 0
Threads seem to work fine as well
from threading import Thread
def play():
import sounddevice as sd
print(sd.rec(1024))
proc = Thread(target=play)
proc.start()
proc.join()
Thanks for the bug report!
This seems to be platform-dependent. When I run your code on my Debian Linux system, I get:
TypeError: Unable to determine number of input channels
If I specify a concrete number of channels, it seems to work.
What happens if you specify a concrete device ID?
Either way, it looks like the sounddevice module has some problems when used with multiprocessing.
I don't really know if I can do anything to improve this. If anyone has an idea, please speak up!
I get the same result as @mgeier on my debian box. When I change the code to play() instead, it works without issue. However, when I move the import sounddevice statement outside of the target function I get the same error as @devxpy). Interestingly, if I comment out the initialize() call in the sounddevice module, and instead manually call it in the example code, the issue goes away.
@devxpy would you try the following code?
from multiprocessing import Process
import sounddevice as sd
def play():
sd._initialize()
sd.rec(1024)
sd._terminate()
proc = Process(target=play)
proc.start()
proc.join()
I was running into this with my own Cython multiprocessing project, and moving the import into the target process's __init__ (instead of as a top-level import) fixed it. Thanks to #309 for some extra clues.