GNU/Linux desktop sound systems, that is.
Experimenting with DJing and music production using only Free Software has resulted in some modifications to how audio is handled on my laptop. This post is to talk a little bit about some of the tradeoffs involved, and some of the problems that came up, including those I still haven’t dealt with.
I had been running a subset of GNOME 3, with awesome for my window manager, with default-configuration PulseAudio (and libasound2-plugins, to expose this to ALSA-only programs) for sound, on Debian testing. This setup has served me well for many years. In April I began using Mixxx to engage in some DJing, as opposed to just playing songs as-is (usually using sox), for my show on WJHU; because PulseAudio adds too much latency for this, I merely disabled autospawn and remembered to do a “pulseaudio -k” before starting Mixxx, and a “pulseaudio –start” after I was finished, and used my device directly via ALSA from Mixxx, which worked very well. Until the production part entered the picture, this is the only PulseAudio configuration change I ever needed to make.
Starting to play with production led me, naturally, to Ardour 3. This required me to set up JACK. It’s getting that working with everything else where the problems begin to arise. (Notably, though, very few of these problems are actually JACK’s fault, as you’ll soon see.)
JACK can mix multiple application streams into one output, just like PulseAudio. libasound2-plugins has a plugin for exposing JACK to ALSA-only programs. This suggests that PulseAudio should go, especially since I never use PulseAudio’s application-specific volume control and don’t rely on transferring active streams on hotplug, which are really the only major features I’d lose by doing that.
But there’s plenty of stuff I use day-to-day that specifically wants PulseAudio. Solution: reconfigure PulseAudio to run on top of JACK. (This also preserves my ability to turn PulseAudio’s volume above 100%, which I semi-regularly find myself doing when confronted with watching a video whose audio track is far quieter than it should be.)
Problem: The volume control keys only affect PulseAudio. (Remember, this is a laptop, so there is no physical volume control slider or knob.) For anything directly using JACK, I have to instead open up alsamixer, point it at the real audio device (since it comes up pointed at PulseAudio), and adjust the volume that way, then either do it again or adjust PulseAudio to compensate when I’m finished with the direct-JACK program. The volume control keys are currently handled by gnome-settings-daemon, which nowadays only supports changing PulseAudio’s volume. I’ll have to have something else handle those keys if I want to change the volume of the actual audio device directly (which would be much better).
There’s also MIDI to deal with. I had to get MIDI through JACK for Ardour, which I initially did with a2jmidid (because old documentation came up first when I searched for a solution), but now do with “-X seq” at the end of my .jackdrc (invoking JACK’s built-in implementation), as I didn’t like having to remember to start yet another daemon. Since every MIDI application I care about running uses PortMIDI, I don’t have to worry about JACK’s exclusive use of the underlying devices, as everything can access it through JACK. I also blacklisted the snd_seq_dummy kernel module so as not to get a virtual MIDI Thru port, which has often annoyed me and which JACK makes completely redundant. It’s nice to see that this setup supports hotplugging of MIDI devices, meaning I don’t have to dig around in qjackctl after plugging or unplugging an instrument or (for DJing) my newly-acquired Numark Mixtrack, or starting or killing TiMidity.
Speaking of TiMidity, I can’t just leave it running under this setup, as much as I would like to, since JACK will hold the virtual MIDI ports TiMidity creates perpetually open, causing it to spend a non-trivial amount of CPU time synthesizing silence. So I just start it by hand when I need it, and kill it afterward. I don’t often need MIDI software synthesis, so I just accept this. (I kind of wish it supported creating its ports within JACK rather than within ALSA. Maybe I should see what it would take to do that.)
Finally, there’s the issue of cuing in Mixxx under this setup, which I haven’t had to deal with yet because JACK only entered the picture after summer break started (and therefore WJHU-season ended). Before I set up JACK so I could start playing with Ardour, I acquired a cheap USB audio device so I had an independent audio output I could use for song cuing while DJing with Mixxx. Because I already had two independent audio outputs, I purchased a Mixtrack rather than springing for a Mixtrack Pro, which contains independent audio outputs of its own but is otherwise exactly the same as the Mixtrack. But JACK seems to strongly discourage (with very good reasons) use over multiple audio interfaces, and even if you try, doesn’t handle hotplugging particularly gracefully. (Sure, there’s alsa_out, but that would add latency, and it’s essential that the mix output and the cuing output have exactly the same amount of latency.) I want JACK involved in the main output to open up the possibility of doing call-ins with a VoIP program with the caller able to hear what’s going on. The logical thing is to just use the USB device directly (sans JACK) for the cuing, but Mixxx currently requires all audio I/O to be done through the same API, so I can’t direct the mix to JACK and the cuing output to the USB device via ALSA.
I’ve really come to like JACK, and hopefully I can find good solutions to these problems that don’t make my system less convenient to use for ordinary things involving sound. Suggestions are welcomed.