0

Background:

Trying to do some audio processing in python3 in a docker image running on the cloud.

Problem:

PyAudio looks for ALSA and JACK audio servers, and ALSA at least needs to have a device.

Not Solutions:

I was initially trying to do it with only PulseAudio Sound Server but this is inadequate.

Sharing /dev/snd/ is not scalable, even if the cloud service happened to have a sound card installed it can only serve a limited number of users. This is the approach that most of the other questions end up recommending.

Possible Solutions on which I would like advice:

I understand that you can create a dummy soundcard in ALSA with the snd-aloop module. This has led to a number of further questions:
- getting access to this module necessitates having privileges that I’m not certain I will have on a cloud service, such as accessing the host machine and modprobing modules into the kernel
- I can try building the modules from source

JACK sound server as an alternative sound server. That is what I'll look into now, I just hope it isn't as problematic as an ALSA virtual server.

Other things to think about:

Perhaps I need to ditch PyAudio altogether?
My incoming audiostream can see pulseaudio, so perhaps https://pypi.org/project/pulsectl/ might be more useful, or something like https://github.com/kubikb/py-audio-docker

Most similar questions:

https://stackoverflow.com/questions/57882375/emulate-sound-card-alsa-snd-dummy-docker-kernel-rebuild-alsa-snd-dummy

How to get alsa dummy soundcard on debian in Docker

1

Solution

Using the PySoundIo library I managed to set up a virtual soundcard in a docker container without /dev/snd and process incoming audiostreams (from a SIPclient) in python3.

Things that didn't work:

PyAudio looks for a device, so basically expects ALSA and /dev/snd. NOTE: you can possibly use ALSA with snd-aloop which might be a solution, but requires getting some modules into the kernel of the host machine where your image is, which is a) very difficult and b) not exactly in the spirit of containerization.

It might be possible to set up a dummy sound device with JACK, however this also requires a privileged docker image and lots of fiddling with settings.

Things that did:

The libsoundio library is a godsend, it works out of the box with no device and not even requiring pulseaudio. Unlike everything else I tried, it doesn't segfault upon startup when you don't have /dev/snd.

Pulseaudio is also great, as most devices on linux that use sound are happy to attach to it and take its instructions seriously. Combined with libsoundio it works with almost no hassle and very little fiddling (protip for anyone else actually trying to do this: RUN sed -i 's/; exit-idle-time = 20/exit-idle-time = -1/' /etc/pulse/daemon.conf in your Dockerfile and then pulseaudio --daemonize in your startup.sh is all the work you need to do to get pulseaudio serving).

I think for some applications you wouldn't even need pulseaudio, pysoundio can do some basic tasks without it. But if you want to shuttle audiostreams between different sources and sinks (one of them being some python code), you shouldn't need to look further than pulseaudio with pysoundio.

2
  • Note, per this issue on the page of pysoundio, you should be careful when mixing it with asynchronous libraries, or just in general im not sure exactly how widely that bug can be found Nov 8 '19 at 14:59
  • Thanks, Installing libasound2 and libsoundio1 worked for me (not sure which one did the trick)
    – Bob Ross
    Aug 29 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.