There is two ways to answer this question.
- Either try to make jack work with pulseaudio... the rest of this question will explain how to do that.
- Or... don't try to use both pulseaudio and jack, just replace them with pipewire: pipewire is supposed to be "the new pulseaudio" (it should replace pulseaudio at some points I think, and is already much less buggy than pulseaudio and supports more Bluetooth options). Pipewire emulates both pulseaudio and jack at the same time, and can seamlessly be used with pulseaudio/qjackctl/... to connect pulseaudio and jack applications together (basically pipewire does not make much difference between pulseaudio applications and jack… most of the time I'm not even sure if the application I'm using is running jack or pulseaudio). If you really want to have pain and use pulseaudio + jack... the rest of this question is for you.
A while ago I wrote a command, and someone reported me that after trying all solutions here he was out of luck. But this solution worked for him, so I'll post it here in case someone else can be helped. NB: I'm not claiming this solution is the most elegant one, but it did the job quite well for me:
- I can start/stop jack by just clicking the start/stop button and the switch is automatic between pulseaudio and pavucontrol
- it automatically connects all current playing softwares to jack (that's why there is this ugly grep, let me know if you have a better solution)
- it also makes sure that pulseaudio application can also use the microphones
This solution may be slighly improved by unloading correctly the modules when quitting Jack, maybe using the ugly grep proposed here, but I didn't really found any benefit for me.
Note also that I give quite detailed instructions on how to debug such issues.
My solution (see theory below to understand why it works/fails and debug any potential issue)
Install:
$ sudo apt install jack2 pavucontrol qjackctl pulseaudio-module-jack.
Run qjackctl:
$ qjackctl
Click on Setup
, and check that the output Interface is the correct one (if you have an HDMI output for example this check may be important). In my case, I'll just use the default and I'll come back here if I've some issues later.
Then, in the advanced tab, I replaced the Server Prefix jackd
with pasuspender -- jackd
. This is supposed to tell pulseaudio to temporarily let jack manage the sound card. I'm not sure if it's really required, but I guess it cannot hurt:
Then, in the tab "Options", put in the Execute script after Startup
the following code:
pactl load-module module-jack-sink && pactl load-module module-jack-source && pactl set-default-sink jack_out && pacmd set-default-source jack_in && pacmd list-sink-inputs | grep index | sed 's/ *index: *//g' | xargs -I{} pacmd move-sink-input "{}" jack_out
The goal of this command is to create new outputs (sink) to pulseaudio that points to jack, to enable this new sink by default (all newly open applications will write to jack), and it also change the output of all the existing applications to make sure they point to jack.
Then, to make sure pulseaudio restarts when jack is closed, I also added in the field Execute script after Shutdown
:
pacmd suspend false
That's it! Now, you just need to save by clicking on Apply
and to click on Start
to start jack:
You should see something like that if it works (and of course no errors):
A bit of theory to understand why it works, or why it fails
So basically, you can't play sound because only one program can play sound at the same time on the same sound card. So when Jack is playing, pulseaudio is blocked. Now, it also turns out that most desktop applications can talk to pulseaudio but not to Jack. So when Jack is on, you just don't have sound anymore. The trick is to route the pulseaudio trafic to Jack with something like that:
application -> pulseaudio -> Jack -> sound card
Note that all links must be correctly configured. We will see now how they are configured and how to check if they are configured correctly.
So to create the link pulseaudio -> Jack
we are going to load a module that creates a new pulseaudio sink (i.e. a virtual output device) called Jack sink
: that way any applications writing in that sink will be redirected on Jack. You could have several already existing sinks, like one for the internal audio, and if you have a bluetooth headset, you can have one sink for it too. To check on which sink an application is actually playing, install and run pavucontrol
(pavucontrol
is super useful anyway for all sound-related stuff, since you can control basically everything from it). You can see the list of sinks in a tab named like Input devices
(sorry if the translation is bad), in my case I have right now 2 sinks (jack is not yet loaded):
If you just have one sink, you may not see anything interesting, but if you have several sinks, you can check in the first tab which application is playing on which sink (here you see that firefox is playing on my bluetooth headset), and you can change it if needed:
So if you have some issues, you can:
- link
pulseaudio -> jack
: check that you have a sink corresponding to jack (if not, try to run manually the command pactl load-module module-jack-sink
that was supposed to be run automatically. If it fails, make sure you installed the pulseaudio-module-jack
, and eventually restart pulseaudio by simply killing it killall pulseaudio
. No worries, no need to restart pulseaudio, it respawn automatically.). Also make sure that the volume is not 0%, and that the channel is not muted:
- link
application -> pulseaudio
: check that your applications are writing on that sink. If not, you can manually change the sink (but the startup script was supposed to change the sink automatically) that way:
- link
jack -> sound card
: If you still have troubles (this part could also concern a trouble you have with the softwares that write on jack directly like zynaddsubfx
), check out the Graph
part of jack:
You should start will all nodes packed together, but you can move them to make them easier to see. Then make sure that all applications you want to ear are connected to system
(in my case zynaddsubfx
was not connected automatically). NB: if you have an older version of QJackctl, then you may have tabs instead of this. But it's the same: you will have green inputs/outputs in the "Jack" tab that you can manually connect, the violet ones will be in the "Alsa" tab, and the red ones in the "MIDI" tab... but in fact all external MIDI devices that you plug will appear in the Alsa tab: the reason is that there are two kinds of "MIDI": the legacy Alsa Midi (ports are global to the system), and the more recent Jack Midi (each application can have its own midi input/outputs).
- Troubles with MIDI: In theory, to get midi, you can just connect the violet inputs to violet inputs (or in the Alsa tab in the older version, yes I know it's strange that you need to go in Alsa tab and not Midi to get Midi(!!!) but it's because of the difference between Alsa MIDI vs the more recent but less used Jack Midi). However, it turns out that for some strange reasons,
zynaddsubfx
has some strange defaults values and will appear as "Midi/red" instead of "Alsa/green", making it impossible to connect to an external midi device. More precisely, if you run zynaddsubfx
from the command line without any option or with:
zynaddsubfx -I alsa -O jack
(which means input from Alsa MIDI, output to jack) it should not be a problem, you will be able to connect the MIDI devices:
However, if you run it in a graphical way, the default Jack entry automatically runs zynaddsubfx -I jack -O jack
instead... And it will have the issue that the zynaddsubfx
input will be created in red/MIDI tab, while the actual external MIDI device is in violet/Alsa tab. So it means that you won't be able to map your external midi keyboard to zynaddsubfx
:
The solution is therefore to run zynaddsubfx
using command line without options, or with zynaddsubfx -I alsa -O midi
and everything should work!