Sharing an audio interface on Linux

Ardour (and JACK, which Ardour can use if necessary) is designed to take exclusive control of your audio interface hardware. It does this because it is intended to be a professional tool. We do not anticipate that you want your work with Ardour to be interrupted by system beeps or Youtube videos. Consequently, while running Ardour, other audio-producing applications will not be able to make any sound ... by default.

However, perhaps you do want the beeps or the youtube videos or the skype calls to work while using Ardour. There are several approaches to this.

You might be wondering why this is an issue at all. Well, ironically 20 years ago it wasn't - many audio interfaces at that time allowed multiple applications to use them simultaneously. That started to change as hardware makers pushed the responsibility for handling this sort of thing onto operating systems and software in general.

In late 2019, having multiple applications using an audio interface on any platform implies some sort of "middleware" that coordinates between the audio hardware and the software. On macOS, this is part of CoreAudio, which is in turn part of macOS itself. On Windows using ASIO, you need to use 3rd party tools. On Linux ... well, on Linux it's complicated.

There are two bits of "sharing middleware" for Linux, both aimed at quite different use-cases. JACK is designed for pro-audio/music creation workflows; PulseAudio is designed for desktop applications that handle audio. The good news is that they can cooperate in various ways. In particular, when Ardour or JACK start using an audio interface, PulseAudio will by default "get out of the way" (and returns when they are done). The bad news is that cooperating to share a device between them doesn't happen without some configuration. The rest of this document describes some approaches to getting it to happen.

Final note before we get started: these days (late 2019) we generally recommend using Ardour without JACK unless you specifically need to. If you want to share the audio interface with other applications you will need to use JACK, because Ardour's own ALSA audio/MIDI backend currently can only use a single audio interface at a time.

1. (Recommended) Use multiple audio interfaces ("soundcards")

OK, this is cheating. This doesn't result in Ardour sharing an audio interface with anyone. We still recommend it, however.

You will (probably) connect the two (or more) interfaces to a mixer where their outputs can be combined and controlled.

By default, PulseAudio will try to use every audio interface it finds on your system, where "use" really means "make available to applications". Our goal here is to keep Pulse from using one of our hardware interfaces and send audio to another device (or devices) instead.

  1. Start up pavucontrol, sometimes called the "Volume Control" application on some systems.
  2. Go to the "Configuration" tab. Click on the dropdown menu for the hardware device(s) you want to reserve for Ardour and/or JACK and select "Off"

screenshot of pavucontrol showing off setting

Use Ardour with its own ALSA audio/MIDI backend and be sure to tell it to use the right audio interface.

2. (Simple) Direct From Pulse to JACK

This is the simplest technique, assuming that your Linux distribution has working versions of PulseAudio. However the PulseAudio<->JACK "bridge" is (as of late 2019) still mostly a proof-of-concept, and so although this solution often works, it is not as robust as the one described in the third approach below.

  1. Ensure that the packages qjackctl and pulseaudio-module-jack are installed on your system.
  2. Open qjackctl. In Setup>Options check Execute script after Startup and paste this:

    pacmd load-module module-jack-source channels=2; pacmd load-module module-jack-sink channels=2;

  3. Check Execute script after Shutdown and paste this:

    killall jackd

Now every time you start JACK with QJackctl, it will tell PulseAudio to load (and implicitly use) the Pulse components that allow it to send audio directly to JACK. You will need to connect the "inputs" from Pulse to some "outputs", such as system:playback_1 in order to hear stuff.

Note that this method also allows Pulse-based audio I/O to record/capture audio from JACK as well.

Some Ardour users who use this solution report that for everything in Ardour to work correctly, they need to disable all ALSA hardware devices in pavucontrol's Configuration tab. This particularly applies to faster-than-realtime export from within Ardour.

3. (Robust) From Pulse to JACK via ALSA

This method is more complex than the one mentioned above, but on some systems can be slightly more robust. It also removes the reliance on the Pulse/JACK bridge(s) correct operation.

Step One: activate ALSA loopback support

The Linux audio drivers can do a lot of amazing things. One of them is to support pseudo-devices that don't correspond to real hardware, but can still be used just like another other audio interface to play or record audio. One particular type of pseudo-device is called a "loopback" device, which allows one application to send audio to the device and another to read it. The applications don't (have to) know that they are not interacting with a "real" hardware audio interface - it just works.

Some Linux distributions may ensure that the kernel supports this functionality already, but most do not. Fortunately, fixing that is easy.

Immediate fix (lasts until reboot)
sudo modprobe snd-aloop
Permanent fix
Edit (as root) /etc/modules to contain a line that says: snd-aloop

Step Two: edit ~/.asoundrc

The file ~/.asoundrc is a configuration file used by the low level Linux audio drivers (ALSA). It might not exist for you, or it may already have some existing content. Either way, you need to edit the file to ensure that it contains (at least) these lines:

pcm.jca {
  type hw
  card Loopback
  device 1
  subdevice 0
  hint { description "JACK can receive from ALSA applications here" }
}
This defines a loopback pseudo-device named "jca". Other applications can use it to play audio, and we'll get JACK to "capture" it and deliver it to the output(s) you choose.

Step Three: configure PulseAudio

By default, PulseAudio will try to use every audio interface it finds on your system, where "use" really means "make available to applications". Our goal here is to keep Pulse from using one of our hardware interfaces and send audio via our loopback devices instead.

  1. Start up pavucontrol, sometimes called the "Volume Control" application on some systems.
  2. Go to the "Configuration" tab. Click on the dropdown menu for the hardware device(s) you want to reserve for Ardour and/or JACK, and select "Off"

screenshot of pavucontrol showing off setting

That's it! Well, it should be. One possible complication is that newer versions of PulseAudio will not attempt to use a device if it is already being used by another application. This can sometimes lead to confusion because the loopback device that we created may not show up in pavucontrol's Configuration tab. As long as nothing else is using it, however, it should just work.

Step Four: configure JACK

This is the one step where things get tricky, because how simple it is depends on the version of JACK your system has. Most Linux distributions come with JACK2 by default, and this step is complicated there. Let's talk about the way to do it with JACK1 first.

JACK1 systems

All you need to do here is to make sure that JACK is started with these extra arguments

 -I "desktop:zalsa_in/-djca -c2 -L" 
This tells JACK to load a special internal client called "zalsa_in" which will read 2 channels of audio from the ALSA loopback device we called "jca" in our ~/.asoundrc file. The client will show up with the name desktop in JACK. The -L means that it will configure the loopback to use the same parameters, particular sample rate, that JACK itself is told to use.

How best to make sure that JACK gets these arguments depends a lot on how you start JACK. I put the following into a file called /usr/local/bin/jacki

#!/bin/sh
exec /usr/bin/jackd -I "desktop:zalsa_in/-djca -c2 -L" $@
Then I configured QJackctl (which I use to run JACK) to use jacki as the "server prefix". That means it happens every time I start JACK with QJackctl, and I don't have to think about it at all. There are other ways to do this depending on how you start JACK.

JACK2 systems

... to be written ...

Step Five: connections

When you start JACK now, there will be an extra clients with 2 output ports. The client will be called "desktop", and you will wnat to make sure it is connected to wherever you want your non-JACK applications' audio to be heard. In simple systems, that is most likely system:playback_1 and system:playback_2. On more complex systems ... only you will know. screenshot of QJackctl showing connections

The End

That's it!