System Jack Service
What if we want to set jack to be system service? I know, I know, I read all the fine manuals and a reason behind avoiding system sound daemon, whether it is pulse or jack. But hey - this is my PC, don't tell me what I cannot do!
After all this is HTPC and all services are focused on media. What? Yes, htpc, not a sound production laptop, or HPC media server. And nothing can stop me from doing whatever I want to make my life more cozy.
We will be starting Jack via DBus. Normally if you start trying jack_control
command in the console it will start barfing about missing X and as a consequence inability to create DBus session. This is blatant lie. In fact it just cannot find proper mechanism to initialize session, falls back to X session, and finally dies. To make it happen it is sufficient to initialize session manually: execute dbus-launch
and export its variables to the shell environment. Once done you can use jack_control
to manage jackdbus
daemon.
This is something we can put into upstart service description to start the daemon on startup. Only need to add one missing point. jackdbus
being user session daemon is really expecting HOME
env var to be set - to initialize config under XDG user config. With that in mind we draw something like this:
description "Starts and stops jackd2 system service. Even though general idea is flowd it can be usefull in some cases like system-wide jack-alsa bridge via loop" author "Ruslan N. Marchenko <me@ruff.mobi>" start on runlevel [2345] or local-filesystems stop on runlevel [!2345] emits audio-bus console log env HOME=/root pre-start script if [ ! -f /run/dbus/.env ]; then eval `dbus-launch --auto-syntax` echo "export DBUS_SESSION_BUS_PID=$DBUS_SESSION_BUS_PID" > /run/dbus/.env echo "export DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS" >> /run/dbus/.env chmod 600 /run/dbus/.env fi end script post-start script . /run/dbus/.env jack_control start if [ -f /etc/default/jackd ]; then awk '/^[esdri]/{system("jack_control "$0)}' /etc/default/jackd awk '/^ /{system("jack_load "$0)}' /etc/default/jackd awk '/^>/{ system("jack_connect "$2":capture_1 "$3":playback_1"); system("jack_connect "$2":capture_2 "$3":playback_2"); }' /etc/default/jackd fi end script post-stop script . /run/dbus/.env if [ -f /etc/default/jackd ]; then awk '/^ /{system("jack_unload "$1)}' /etc/default/jackd fi jack_control exit end script
First we define service settings: start on system startup, stop politely, even send own event, if anyone cares (no one does). Next we setting HOME to root's home dir. This is system wide service, let root configure and control it. Pre-start section is initializing DBus session. Here we're using persistent session settings stored in volatile memory filesystem. On boot it will not exist, once created we stick to spawned dbus session till system reboots. Keep that in mind if you decide for some reason clean up dbus sessions. Further on, you can add '[ -f /run/dbus/.env ] && source /run/dbus/.env
' line in ~/.profile
to get DBus session populated to your interactive session. Be aware though - jack's native api calls, like alsa jack plugin, or LADI apps will be possible to execute only from this root session! So it really only does make sense on personless home-server for case like pulling together alsa-loop bridge and, maybe, network protocol stack.
We're using only pre/post scripts since actual daemon is kept by dbus and upstart has nothing to control/respawn. So once session is initialized in pre-start
section, post-start
section is starting actual daemon and does some additional fine tuning. Finally post-stop
stanza is amed to make graceful shutdown.
I've moved additional setup into /etc/default/jackd file so that I can setup my adaptors and other bells and whistles. Comments in file are self-decriptive:
/etc/default/jackd # jack_control command file. All lines not starting # with # ant representing valid jack_control commands # will be executed by jack_control. Lines starting # with space will be processed by jack_load. Lines # starting with > are port groups to connect. iload netmanager jab1 audioadapter -- '-dhw:JABridge -Chw:JABridge,1,0 -Phw:JABridge,1,1 -i2 -o2' hdmi audioadapter -- '-dhw:Generic -Chw:Generic,1 -Phw:VT82xx,0 -i2 -o2' > jab1 system > jab1 hdmi net netadapter > jab1 net
Once daemon is started you can switch to root with sudo, import dbus session from .env file and do jack configuration via jack_control command. Aparently, next step would be to set system pulse server on top of jack bus.
Link... Sun Feb 3 02:14:31 2013 Upd.: Sat Feb 9 21:31:57 2013