2

I am using Python's sounddevice library (which runs PortAudio underneath) to record audio on Linux (Raspbian Buster desktop on RPi 4), but it appears that more than one instance of my script will cause an error PaErrorcode -9985 which I believe is due to PortAudio (or the OS?) not allowing multiple programs to access an audio input at the same time.

I am a noob but read about Try blocks and encapsulated the part of my code that uses sounddevice in a Try block where it keeps retrying until the error code is no longer given. However, it seems that sounddevice will not recognize the input is free even after it becomes free. For example, running sounddevice.default.device on the 2nd instance will produce [-1,3] instead of the first instance's [0,0] even after the first instance closes. Weirdly there are usually only two devices:

1st instance sounddevice.query_devices() result:

* 0 sysdefault, ALSA (128 in, 128 out)
  1 dmix, ALSA (0 in, 2 out)

2nd instance's result:

  0 snd_rpi_hifiberry_dacplusadcpro: HiFiBerry DAC+ADC Pro HiFi multicodec-0 (hw:0,0), ALSA (0 in, 2 out)
  1 sysdefault, ALSA (0 in, 128 out)
  2 dmix, ALSA (0 in, 2 out)
< 3 default, ALSA (0 in, 2 out)

In addition to the Try block like this, I also tried reimporting sounddevice and rechecking but that also did not work. I haven't been able to find any solution from searching the error code, reading the documentation for sounddevice or portaudio. I also looked into a pidfile but that won't help if I can't get sounddevice to re-recognize the proper inputs.

Overall, I am trying to figure out how to get sound device to recognize that the input is free and to use it.

Update: As requested in comments, below is a simple sample script for which two instances cannot be running simultaneously.

import sounddevice
from scipy.io.wavfile import write

mysamplerate = 44100 
myrecording = sounddevice.rec(mysamplerate * 10, samplerate=mysamplerate, channels=1)
sounddevice.wait()
write('output.wav', mysamplerate, myrecording)
rfii
  • 562
  • 3
  • 14
  • can you show your code and the config you have setup? – Nagaraj Tantri Sep 04 '20 at 00:10
  • I added a sample script. The config is a Raspberry Pi 4 running Buster with a Hifiberry shield. – rfii Sep 04 '20 at 02:58
  • I tried running the above code on a windows machine and ran 4-5 similar records. All of them passed without any error. Can you again highlight specifically as to what the whole setup look like? I did not get the instance1 and instance2 in your question. Sample: `import sounddevice as sd from scipy.io.wavfile import write fs = 44100 # Sample rate seconds = 10 # Duration of recording myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=1) sd.wait() # Wait until recording is finished write('output_1.wav', fs, myrecording)` – Nagaraj Tantri Sep 04 '20 at 23:44
  • 1
    does it recognize the freed input if you stop the whole process, that is, if you close and restart your python program? if yes, you can write a python thing or shell script to do that. – antont Sep 05 '20 at 19:42
  • antont, can you explain a bit more? Are you saying I should have a script invoked by crontab that just opens and closes itself until it sees that the input is freed and if so then it should invoke the actual main script? – rfii Sep 11 '20 at 05:40
  • Nagaraj, I am not sure what you're asking. I said the hardware, the OS, and the script. What else do you want me to provide? Happy to do so – rfii Sep 11 '20 at 05:41
  • Switch to pyaudio instead. If the problem persists, install pulseaudio, it will automatically manage concurrent access. Although portaudio will not allow you to open multiple streams to the same device simultaneously. To do that you record data in a separate thread and make it available to all others. – Dalen Sep 11 '20 at 06:25

0 Answers0