if(($ACT == 'edit' || $ACT == 'preview') && $INFO['editable']){ ?> } else { ?> } ?>
Prototype of automatic backend-switching for JACK2 using dbus.
You may know this Mac/OSX feature: one plugs or unplugs an external audio-interfaces and the system automatically switches the sound to the new device. - It may not always be what you want, but it is an very handy feature especially for mobile systems. and here's how to set this up for JACK on GNU/Linux..
First, we need a mechanism to switch the “JACK backend” in order to switch between audio-interfaces. The task includes taking care of re-connecting physical I/O ports in case they're different on each device.
Second, said mechanism needs to be triggered automatically when a new device is connected or if a device goes away. Here's a short annotated demo-video:
(If Flash is installed JavaScript is activated, you can watch a video inside this web page.)
(well yes, I should have ripped out that USB cord more visibly.. sorry, next time. I might use a real camera too, then.)
myjackctl.sh
myjackctl - or similar program to switch JACK-backends.dbus-triggerd
- or a similar tool that runs a hook-script on receiving dbus-signals.Download:
Note: dbus-triggerd
and a jack2
debian packages (source and i386) are available from
deb http://rg42.org/deb/ sid main
jack2
, dbus-triggerd
(or get the debian package).myjackctl.sh
to PATH (~/bin
or /usr/local/bin
), chmod +x
.tail -f ~/.log/jack/jackdbus.log
killall -9 jackd jackdbus # clean start jack_control eps verbose true # tell jackdbus to be verbose myjackctl.sh alsa hw:0 1024 48000 3 # launch jackd on first ALSA interface -p1024 -r48000 -n3 myjackctl.sh alsa hw:1 # switch to second ALSA interface
Launch some jack clients, players etc and repeat testing with myjackctl.sh
.
dbus-triggerd is a tool to trigger shell-commands upon receiving a given dbus-signal.
It can be used to invoke myjackctl.sh
in order to change the JACK-backend if
org.freedesktop.Hal.Manager,member=DeviceAdded
) → use the newly connected device.org.freedesktop.Hal.Manager,member=DeviceRemoved
) → switch to a fallback audio-interface.org.jackaudio.JackControl,member=DeviceError
) → switch to a fallback audio-interface.
The two last are redundant and exclusive. JACKd still needs a patch to send a DeviceError
. Using HAL's DeviceRemoved
may be problematic for setups with more than two sound-cards if the removed device was not currently the one used by JACK.
Example to launch dbus-triggerd
:
#!/bin/sh make || exit killall dbus-triggerd ### switch to sound 'hw:0' on any DeviceError # This requires a patched JACK2, that sends a DeviceError ./dbus-triggerd $@ "type='signal',path=/org/jackaudio/Controller,interface=org.jackaudio.JackControl,member=DeviceError" --shell "myjackctl.sh alsa hw:0" & # This an alternative to the above, using the HAL message #dbus-triggerd $@ --system "type='signal',path=/org/freedesktop/Hal/Manager,interface=org.freedesktop.Hal.Manager,member=DeviceRemoved,arg0=/org/freedesktop/Hal/devices/usb_device_582_74_noserial_if0_sound_card_2" --shell "myjackctl.sh alsa hw:0" & ### switch to external USB sound device 'hw:2' when it's connected ./dbus-triggerd $@ --system "type='signal',path=/org/freedesktop/Hal/Manager,interface=org.freedesktop.Hal.Manager,member=DeviceAdded,arg0=/org/freedesktop/Hal/devices/usb_device_582_74_noserial_if0_sound_card_2" --shell "myjackctl.sh alsa hw:2" &
Here be dragons…
The mechanism for backend-switching is implemented by a shell-script myjackctl.sh
(which call dbus-send
) that controls jack2d by exchanging dbus-messages.
myjackctl.sh
is started with different command-line parameters on-demand by dbus-triggerd
.
org.freedesktop.Hal.Manager,member=DeviceAdded
org.jackaudio.JackControl,member=DeviceError
(requires patch to jack2)org.freedesktop.Hal.Manager,member=DeviceRemoved
Note that myjackctl.sh
uses the org.jackaudio.PatchBay
dbus-API which is broken in jack2-r4120 (see ticket below) and fixed by Nedko in jack2-r4366.
Future: Instead of patching jack2 to send additional messages (here: org.jackaudio.JackControl,member=DeviceError
), the trigger functionality should be built into jackd, but requires a callback to the control API to be added to JACK.
The shell hook-script (myjackctl.sh) could be implemented easier and more flexible using python (jack-control API bindings) or similar language more suitable to parse and provide audio-port mapping and configuration.