Nowadays it's quite easy to make PulseAudio and Jack work together, mostly thanks to the dbus api, but as
soon as a second user enters the scene, by means of the user switcher applet, it's once again an inferior user
experience as compared to what a PulseAudio-only system gives. Generally the second user will get no sound at all, other problems arise when the second user wants to make use of some Jack applications...
So I've been working lately on making it easier to use Jack as the default sound system on a shared workstation, with PulseAudio as a helper for desktop sounds. I've investigated 3 solutions which I'll present here.
In all cases it was necessary to have a system-wide Jack server launched at boot time. First problem: there is no session dbus available at boot time. There are basically 3 ways of solving this:
1. use the system dbus instead by faking the DBUS_SESSION_BUS_ADDRESS. This will require some modification of system policies to allow the owning of the org.freedesktop.ReserveDevice1.Audio0 name
2. launch a session bus, which will be used only for this purpose
3. hack Jack to allow bypassing the whole thing
I've chosen 3, the formers do no really reserve anything anyway as the buses are not connected to each other. By passing the JACK_NO_AUDIO_RESERVATION environment variable I can now disable the audio_acquire/audio_release callbacks.
The first solution that comes to mind is to make this system-wide server run in promiscuous mode, so I've exported JACK_PROMISCUOUS_SERVER globally (in /etc/environment). Problem: for this to work, the server and every single Jack application (including the pulse-jack bridge) must be running with a 0000 umask, which sounds a bit scary to me. So I've hacked a little enhancement to the promiscuous mode which makes it possible to pass the name or gid of a group through the JACK_PROMISCUOUS_SERVER variable. In that case, the sockets, shared memory segments and semaphores have their permissions tightened so only members of that group will get access to them. More importantly, it is not needed anymore to fiddle with the umask, even if no group is given.
With that in place, and after having changed the default PulseAudio configuration (/etc/pulse/default.pa
) to statically load the pulse-jack bridge, each user session has its shiny desktop sounds working, and every user is able to run Jack applications whenever they want.
One (big) con is that as everybody share the same Jack server the graph may easily become incomprehensible (jack_keyboard, jack_keyboard-01, jack_keyboard-02, all belonging to different users...). Also, if a user start the Jack transport, it will be started for all users !
That's where the two other solutions comes into play (they really are to variants of the same solution).
The idea is to have a main system-wide Jack server in charge of the hardware driver, and a second per-user Jack server launched through dbus api, connected by some way to the former, and handling the connections with the various Jack applications of that user session.
This can easily be implemented by using NetJack bound to the loopback interface.
In this solution, the promiscuous mode is not necessary anymore. The netmanager have to be loaded in the main server at boot time, bound to the 127.0.0.1 address, with the auto-connect feature enabled. The default.pa
should use jackdbus-detect and a .config/jack/conf.xml must be put in each user's HOME so the net driver is loaded when a Jack server is spawned by the user.
Now, each user will only see his/her own applications in the graph, but the Jack transport is still unique across the NetJack network. Another problem is the overhead introduced by NetJack.
To address these, I've hacked a new JackProxyDriver which is similar to the JackNetDriver, but only uses plain Jack API to talk to its upstream server so the overhead is reduced to its minimum.
In this solution, the promiscuous mode is again necessary, but only for the main server. The per-user server will run in normal mode toward its clients, and will use a promiscuous connection to talk to the main server. The .config/jack/conf.xml must be changed to load the proxy driver.
If someone is interested to try it out, I've setup a PPA (currently only for 14.04) with a jackd2 package based on KXStudio's one.