This is a sister article to my original gist, but this time instead of using NetJack2, we're going to directly use ALSA and /dev/snd by passing them into the container. We should see native performance but at the downside of having to dedicate a soundcard for exclusive use to the container and the loss of high performance OS X/Windows compatibility.
- The host OS is Linux
- You've got a free ALSA soundcard with no daemon attached to it (i.e. no PulseAudio or Jack), however you can have a daemon running on other soundcards.
- You've got Docker setup correctly and are able to run
docker run hello-world
For reference I'm running Arch Linux.
Because we're running a container rather than a virtual machine, the kernel inside the container is the host kernel, in particular for us /dev/snd is the same both inside and out if we give access via (--device /dev/snd).
This will cause an issue with group IDs though, as frequently the host OS and the container OS will have difference values for the audio group in /etc/group. Assuming we don't want the container processes to run as root we will need to give our user membership of the host audio group specified as a gid.
We can do this with the following line added to our docker run:
--group-add $(getent group audio | cut -d: -f3)
See more on Jess Frazelle's GitHub repo.
There are a variety of flags for configuring realtime behaviour with Docker. I can't claim to understand them, but if you have a realtime kernel installed then add the following to your docker run line:
--cpu-rt-runtime=950000
See the "configure the realtime scheduler" section on the Docker website for more details.
The default compile of Jack2 on most distros needs D-Bus to be running (even if it's not the jackdbus version), this is normally started by your desktop environment, but here we are manually starting a session with dbus-run-session. The alternative to compile Jack2 manually without the requirement for D-Bus.
build: build the Docker imagenorns/supercollider.run: run the image, leaves you at ansclangterminal,Ctrl-Dto exitsclangand the container.run-bash: runs the image, but doesn't startsclang, instead leaves you at abashprompt.shell: gives you abashprompt on an already running instance (e.g. either frommake runormake run-bash).
-
Clone this Gist, and
cdto it. -
Copy
jackdrc_sampletojackdrcand changehw:X(e.g.hw:2) to the index of the soundcard you wish to use (useaplay -lto list soundcards and their indices). -
Make sure that the soundcard you wish to use in the container has no sound daemon attached to it, for example if you're using Jack then stop it by running:
jack_control stop -
In a terminal run:
make build make runThis should leave you at an
sclangprompt. (TypeCtrl-Dif you need to exitsclang, that will also exit the Docker container.) -
In
sclangwe need to bootscsynthby running:s.boot;Watch the output messages, it can be somewhat tricky figuring out if it hasn't succeeded.
(You may need to press
enterto get thesc3>prompt back.) -
Now let's generate some audio from SuperCollider, in the
sclangterminal:{ SinOsc.ar(440)!2 }.play;then to stop (all) sound:
s.freeAll;Fingers crossed it worked and there were no audio glitches.
Try some of the sc140 compositions (be-warned some of them are deliberately glitchy). After pasting one into the sclang command line you'll need to type s.freeAll; to stop audio.
No 11 works well:
play{VarSaw.ar((Hasher.ar(Latch.ar(SinOsc.ar((1..4)!2),Impulse.ar([5/2,5])))*300+300).round(60),0,LFNoise2.ar(2,1/3,1/2))/5}//#supercollider