====== JACKdbus - Desktop integration - backend-switching ======
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 [[http://jackaudio.org|JACK]] on GNU/Linux..
===== Overview =====
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:
file=/_media/pub/av/jackdbus.flv&image=/_media/wiki/jackdbus.png
(well yes, I should have ripped out that USB cord more visibly.. sorry, next time. I might use a //real// camera too, then.)
===== Prerequisites =====
* recent jack2 from [[http://jackaudio.org]] + patcheset [[http://trac.jackaudio.org/ticket/213]]
* ''myjackctl.sh'' [[wiki:jack2contol|myjackctl]] - or similar program to switch JACK-backends.
* ''dbus-triggerd'' - or a similar tool that runs a hook-script on receiving dbus-signals.
Download:
* [[http://rg42.org/gitweb/?p=myjackctl.git;a=blob_plain;f=myjackctl.sh|Download standalone myjackctl.sh]]
* [[http://rg42.org/gitweb/?p=dbustriggerd.git;a=snapshot;h=HEAD|download dbus-triggerd source]]
Note: ''dbus-triggerd'' and a ''jack2'' debian packages (source and i386) are available from
deb http://rg42.org/deb/ sid main
===== Installation and testing =====
- get ''jack2'', patch, compile and install (or get the debian package).
- compile and install ''dbus-triggerd'' (or get the debian package).
- download and install ''myjackctl.sh'' to PATH (''~/bin'' or ''/usr/local/bin''), ''chmod +x''.
- open a window to watch ''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''.
===== Automating it with dbus-triggerd =====
[[oss:dbustriggerd:start|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
* a new audio-interface is connected (system-dbus ''org.freedesktop.Hal.Manager,member=DeviceAdded'') -> use the newly connected device.
* an audio-interface is disconnected (system-dbus ''org.freedesktop.Hal.Manager,member=DeviceRemoved'') -> switch to a fallback audio-interface.
* JACK daemon signals device-error (session-dbus ''org.jackaudio.JackControl,member=DeviceError'') -> switch to a fallback audio-interface.
The two last are redundant and exclusive. JACKd still needs a [[http://trac.jackaudio.org/attachment/ticket/213/0003-signal-device-error-via-dbus.diff|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'':
extern>http://rg42.org/gitweb/?p=dbustriggerd.git;a=blob_plain;f=doit.sh;hb=HEAD
===== Implementation =====
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)
* (or) ''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.
====== References ======
* http://lists.linuxaudio.org/pipermail/linux-audio-user/2011-February/076696.html
* http://jackaudio.org/
* http://trac.jackaudio.org/ticket/213
{{tag>audio floss jack linux}}