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 ansclang
terminal,Ctrl-D
to exitsclang
and the container.run-bash
: runs the image, but doesn't startsclang
, instead leaves you at abash
prompt.shell
: gives you abash
prompt on an already running instance (e.g. either frommake run
ormake run-bash
).
-
Clone this Gist, and
cd
to it. -
Copy
jackdrc_sample
tojackdrc
and changehw:X
(e.g.hw:2
) to the index of the soundcard you wish to use (useaplay -l
to 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 run
This should leave you at an
sclang
prompt. (TypeCtrl-D
if you need to exitsclang
, that will also exit the Docker container.) -
In
sclang
we need to bootscsynth
by running:s.boot;
Watch the output messages, it can be somewhat tricky figuring out if it hasn't succeeded.
(You may need to press
enter
to get thesc3>
prompt back.) -
Now let's generate some audio from SuperCollider, in the
sclang
terminal:{ 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