MRW

Timidity und Jack Audio Daemon

Problem

Timidity funktioniert perfekt, um Midi-Dateien nach «Musik» zu wandeln, um sie dann ohne spezielles Ausgabegerät auf einer normalen Soundkarte mittels Alsa auszugeben.

Startet man timidity mit den Optionen -Os -iAD, kann man mittels kmid Midi-Dateien hören.

Sobald der Jack Audio Daemon jackd gestartet ist, geht das nicht mehr. Man hört keinen Ton, auch wenn man die Midi-Ausgabe mittels qjackctl auf Timidity leitet. Programme wie Rosegarden benötigen den Jack Audio Daemon, um ihre Musikdaten vom gewünschten Eingabegerät auf das richtige Ausgabegeräte zu leiten. Hängt man hingegen ein Midi-Keyboard an (in meinem Fall ein Yamaha PSR-E403), dann kann man dieses als Ausgabegerät setzen und hört die Ausgabe.

Lösung

Timidity muss mit anderen Optionen gestartet werden. Zuerst müssen alle bestehenden Instanzen abgeschossen werden. sudo pkill timidity erledigt die schmutzige Arbeit. Danach startet man zuerst den jackd mit den gewünschten Optionen. Danach startet man timidity mit -Oj -iAD und alles wird gut.

Neues Problem: Verzögerte ruckelige Ausgabe in Rosegarden

Verbessert mit:

timidity -B2,8  -Oj -s 44100 -iA --realtime-priority=99 -EFreverb=0 -EFchorus=0

Angeblich ist Timidity mit Jack problematisch. Fluidsynth und qsynth (ein GUI für fluidsynth) sollen besser sein.

Automatischer Start

Unter Ubuntu wird Timidity automatisch unter root gestartet. Ich habe das dazugehörende Skript in /etc/init.d kopiert und angepasst. Danach muss man dafür sorgen, dass /etc/init.d/timidity nicht mehr aufgerufen wird, dafür aber die zwei neuen Skripte.

Nachteil dieser Methode: Wenn jackd als root gestartet wird, müssen alle Anwendungen, die jackd verwenden, ebenfalls unter root laufen. Vorteil: Man kann dafür den Prozess mit Echtzeitpriorität laufen lassen.

Unter SuSE dürfte es ähnlich gehen, nur wird insserv verwendet statt update-rc.d. Die Skripte dürften ebenfalls leicht abweichen.

Die Skripte dazu folgen weiter unten.

Ich persönlich ziehe es vor, qjackctl zu benutzen, um den Jack Audio Daemon als normaler Benutzer zu starten, und danach mittels Kommandozeile oder alt+F2 den Befehl timidity -Oj -iAD einzugeben, und Timidity so zu starten. Mann kann den Start von Jackd und Timidity auch in ~/.profile eintragen und so bei jeder Anmeldung automatisch starten.

Skripte

Bitte die beiden folgenden Skripte erstellen und mittels sudo chmod ugo+x /etc/init.d/jackd /etc/init.d/timidity-jackd ausführbar machen:

/etc/init.d/jackd

#!/bin/sh
# start jackd audio daemon
 
### BEGIN INIT INFO
# Provides: jackd
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Default-Start:  2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop jackd
# Description: Jack is an Audio Daemon
### END INIT INFO
 
. /lib/lsb/init-functions
 
NAME="jackd"
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/${NAME}
DESC="Jack is an Audio Daemon"
PIDFILE=/var/run/${NAME}.pid
 
set -e
 
test -x ${DAEMON} || exit 0
 
PARAMS="-R -P89 -dalsa -dhw:0 -r4800 -p128 -n3 -S"
[ -r /etc/default/jackd ] && . /etc/default/jackd
 
START="--start --quiet --exec ${DAEMON} --pidfile ${PIDFILE} -- ${PARAMS}"
 
case "$1" in
  start)
	log_daemon_msg "Starting" "${NAME}"
	log_begin_msg "Starting $DESC..."
	if start-stop-daemon ${START} >/dev/null; then
		log_end_msg 0
	else
		log_end_msg 1
		exit 1
	fi
	;;
  stop)
	log_begin_msg "Stopping $DESC..."
	if start-stop-daemon --stop --quiet --oknodo --pidfile ${PIDFILE} \
          --name $(basename ${DAEMON}) --retry 10 ; then
		log_end_msg 0
	else
		log_end_msg 1
		exit 1
	fi
	;;
  restart|force-reload)
  	$0 stop
	exec $0 start
  	;;
  *)
    echo "Usage: $0 {start|stop|restart|force-reload}" >&2
    exit 1
esac
 
exit 0

/etc/init.d/timidity-jackd

#!/bin/sh
# timidity for jackd
 
### BEGIN INIT INFO
# Provides: timidity-jackd
# Required-Start: $local_fs jackd
# Required-Stop: $local_fs jackd
# Default-Start:  2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop timidity-jackd
# Description:  Timidity++ is a very high quality software-only MIDI sequencer
#        and MOD player. It is started for Jack Audio Daemon
### END INIT INFO
 
. /lib/lsb/init-functions
 
NAME="timidity-jackd"
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/${NAME}
DESC="Timidity++ Jack Audio Daemon midi emulation"
PMIDI=/usr/bin/pmidi
PIDFILE=/var/run/${NAME}.pid
 
set -e
 
test -x ${DAEMON} || exit 0
test -x ${PMIDI} && pmidi_enabled="true" || pmidi_enabled="false";
 
TIM_JACKDSEQPARAMS="-Oj"
[ -r /etc/default/timidity-jackd ] && . /etc/default/timidity-jackd
PARAMS="${TIM_JACKDSEQPARAMS} -iAD"
 
START="--start --quiet --exec ${DAEMON} --pidfile ${PIDFILE} -- ${PARAMS}"
 
case "$1" in
  start)
	log_daemon_msg "Starting" "${NAME}"
	log_begin_msg "Starting $DESC..."
	if start-stop-daemon ${START} >/dev/null; then
		log_end_msg 0
	else
		log_end_msg 1
		exit 1
	fi
	;;
  stop)
	log_begin_msg "Stopping $DESC..."
	if start-stop-daemon --stop --quiet --oknodo --pidfile ${PIDFILE} \
          --name $(basename ${DAEMON}) --retry 10 ; then
		log_end_msg 0
	else
		log_end_msg 1
		exit 1
	fi
	;;
  restart|force-reload)
  	$0 stop
	exec $0 start
  	;;
  *)
    echo "Usage: $0 {start|stop|restart|force-reload}" >&2
    exit 1
esac
 
exit 0

Automatisch starten

Zuerst den alten timidity entfernen:

update-rc.d -f timidity remove

Dann die neuen Dienste starten:

update-rc.d jackd start 91 2 3 4 5 . stop 92 0 1 6 .
update-rc.d timidity-jackd start 92 2 3 4 5 . stop 91 0 1 6 .

Später wieder entfernen: Die beiden Skripte löschen (oder nicht erst löschen, dafür mit Option -f) und:

update-rc.d timidity-jack remove
update-rc.d jack remove

Jackd mit Realtime als gewöhnlicher User

(Tipp aus c't-special Linux 01/08)

Einfügen in /etc/security/limits.conf:

@audio - nice -10
@audio - memlock unlimited
@audio - rtprio 99

Nun kann man als Benutzer und Mitglied der Gruppe audio den Jackd auch mit nice -10 und der Option -R starten:

nice -10 jackd -R -P89 -dalsa -dhw:0 -r4800 -p128 -n3 -S

Auch Musiksoftware kann man nun in höherer Priorität starten, z.B. Timidity:

nice -10 timidity -Oj -iAD