python-sounddevice icon indicating copy to clipboard operation
python-sounddevice copied to clipboard

When using "multiprocessing": Illegal combination of I/O devices [PaErrorCode -9993]

Open devxpy opened this issue 6 years ago • 3 comments

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()

devxpy avatar Aug 12 '18 17:08 devxpy

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!

mgeier avatar Aug 13 '18 19:08 mgeier

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()

tgarc avatar Aug 14 '18 18:08 tgarc

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.

combs avatar Jan 28 '22 19:01 combs