JACK and Headphones

By: Ted Felix

The Problem

JACK doesn't work when I plug headphones into my laptop. The sound from the speakers stops, but there is also no sound in the headphones.

The Cause

In my case, my laptop has a soundcard with four channels. The first two channels, 0 and 1, go to the speakers, while the remaining two channels, 2 and 3, go to the headphones. It appears that applications that use JACK only connect to the first two channels of my laptop's soundcard.

.asoundrc

The best solution I have at this time is to set up a virtual device in my .asoundrc file that maps two channels of audio to all four channels on the soundcard. Here's my .asoundrc:

# hpfixpb - Headphone Fix Playback Side
# This one routes two channels to hw:0's channels 1,3 and 2,4.
# Requires JACK's "-P" option as there's no capture side to this.
# JACK complains that this brings in the plug layer.  When using plughw:0
# I have all sorts of trouble.  But this works fine for me.  I think it is
# safe to ignore JACK's warnings.
pcm.hpfixpb {
	type route

	# Our slave is "hw:0" which has 4 channels
	slave.pcm "hw:0"
	slave.channels 4

	# Transfer Table
	# ch0 => slave ch0 (speaker left), volume = 1 (full)
	ttable.0.0 1
	# ch1 => slave ch1 (speaker right), volume = 1 (full)
	ttable.1.1 1
	# ch0 => slave ch2 (headphone left), volume = 1 (full)
	ttable.0.2 1
	# ch1 => slave ch3 (headphone right), volume = 1 (full)
	ttable.1.3 1
}

# We also need a "ctl" or else ALSA will complain.  Note that there
# is no "device" line.
ctl.hpfixpb {
	type hw
	card 0
}

# hpfix - Headphone Fix
# This combines hpfixpb on the playback side with the hardware interface on
# the capture side to give us one virtual device "hpfix" we can use to fix
# the headphone problem.  Just launch jackd like this:
#   jackd -d alsa --period 32 --device hpfix
# Tested both sides with ardour and audacity.  No problems.
pcm.hpfix {
	type asym
	playback.pcm "hpfixpb"
	capture.pcm "hw:0"
}

# Again, the mandatory "ctl".
ctl.hpfix {
	type hw
	card 0
}

With that in place, we need to tell JACK to connect to our new virtual device "hpfix":

jackd -d alsa --period 32 --device hpfix

JACK will complain as it looks like you are connecting through ALSA's plug layer. However, I don't believe this uses the plug layer in such a way that would hurt performance. It works great for me.

jack_connect

A less satisfactory solution is to adjust JACK's audio connections to the soundcard. The problem is that JACK leaves it up to the application to make the required connections. Most applications make their own connections and assume every soundcard has just two channels. If we go in and mess with the connections an application has made, there's no telling what might happen. Sometimes it works. Sometimes it doesn't. As an example, Audacity changes the name of its ports each time you press "play". This makes it impossible to get a reliable connection set up.

To examine the JACK ports and connections, use jack_lsp with the -c option:

jack_lsp -c

On my system when the headphones weren't working, I saw this with JACK and fluidsynth running:

system:capture_1
system:capture_2
system:playback_1
   fluidsynth:l_00
system:playback_2
   fluidsynth:r_00
system:playback_3
system:playback_4
fluidsynth:l_00
   system:playback_1
fluidsynth:r_00
   system:playback_2

From this we can see that fluidsynth:l_00 is connected to system:playback_1 and fluidsynth:r_00 is connected to system:playback_2. But what about system:playback_3 and system:playback_4? Those are the headphones and they aren't connected to anything. So, we can use jack_connect to send fluidsynth's output to the headphones:

jack_connect fluidsynth:l_00 system:playback_3 jack_connect fluidsynth:r_00 system:playback_4

Now taking a look at the connections:

$ jack_lsp -c
system:capture_1
system:capture_2
system:playback_1
   fluidsynth:l_00
system:playback_2
   fluidsynth:r_00
system:playback_3
   fluidsynth:l_00
system:playback_4
   fluidsynth:r_00
fluidsynth:l_00
   system:playback_3
   system:playback_1
fluidsynth:r_00
   system:playback_4
   system:playback_2

And the headphones are working perfectly.

Note that some MIDI software may change the various JACK connections, so if something seems strange, this is probably why. As an example, closing rosegarden will disconnect all connections.

If you prefer something a bit more graphical, patchage will also show you these JACK audio connections and let you set up whatever you need.

Links

Post at LinuxMusicians.com - This is one of the first places I tried for fixing this. Learned a lot.

License

Copyright (C) 2011, Ted Felix

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. See http://www.gnu.org/licenses/fdl.html for the full text of this license.

<- Back to my Linux page.

Copyright ©2011, Ted Felix. Disclaimer