Controlar Jack con QDbus

anecochea
#1 por anecochea el 31/05/2012
Como muchos sabrán la nueva versión de jack viene en dos formatos: híbrido y dbus. El formato híbrido se puede usar de la manera tradicional o bien vía dbus. El segundo formato hace uso exclusivo de dbus, pero, al parecer, no es compatible con qjackctl (al menos no en mi caso).

Jack-dbus es una tecnología sumamente innovadora que abre muchas posibilidades para Jack y aplicaciones auxiliares, aunque todavía es un tanto experimental.

Quería hacer un pequeño tutorial sobre como controlar jack a través de un programa para gestionar dbus desde la consola, qdbus, en este caso. Si bien existe jack_control que es una aplicación para la consola especializada en controlar jack via dbus, utilizar qdbus o dbus-send nos permitirá ir un poco más a las entrañas de dbus y esto nos permite expandirnos a otros experimentos interesantes como controlar jack con un script en python.

primero comprobamos si está jack entre las aplicaciones dbus. Para esto solo escribimos qdbus en la consola:
Alguien escribió:
$ qdbus
...
org.freedesktop.ReserveDevice1.Audio0
org.jackaudio.service
:1.57
:1.6
...

El resultado es bien largo, pero si aparecen las líneas de arriba quiere decir que vamos bien.

Ahora vamos a listar las distintas subdirecciones que tenemos en jack dbus
Alguien escribió:
$ qdbus org.jackaudio.service
/
/org
/org/freedesktop
/org/freedesktop/ReserveDevice1
/org/freedesktop/ReserveDevice1/Audio0
/org/jackaudio
/org/jackaudio/Controller


El siguiente comando nos permitirá obtener un listado de métodos disponibles para Jack:
Alguien escribió:
$ qdbus org.jackaudio.service /org/jackaudio/Controller
method QString org.freedesktop.DBus.Introspectable.Introspect()
method void org.jackaudio.JackControl.AddSlaveDriver(QString driver_name)
method uint org.jackaudio.JackControl.GetBufferSize()
method double org.jackaudio.JackControl.GetLatency()
method double org.jackaudio.JackControl.GetLoad()
method uint org.jackaudio.JackControl.GetSampleRate()
method uint org.jackaudio.JackControl.GetXruns()
method bool org.jackaudio.JackControl.IsRealtime()
method bool org.jackaudio.JackControl.IsStarted()
method void org.jackaudio.JackControl.LoadInternal(QString internal)
method void org.jackaudio.JackControl.RemoveSlaveDriver(QString driver_name)
method void org.jackaudio.JackControl.ResetXruns()
signal void org.jackaudio.JackControl.ServerStarted()
signal void org.jackaudio.JackControl.ServerStopped()
method void org.jackaudio.JackControl.SetBufferSize(uint buffer_size_frames)
method void org.jackaudio.JackControl.StartServer()
method void org.jackaudio.JackControl.StopServer()
method void org.jackaudio.JackControl.SwitchMaster()
method void org.jackaudio.JackControl.UnloadInternal(QString internal)
method bool org.jackaudio.Configure.GetParameterConstraint(QStringList parameter, bool& is_strict, bool& is_fake_value, QDBusRawType::a(vs values)
method QDBusRawType::(ysss) org.jackaudio.Configure.GetParameterInfo(QStringList parameter)
method bool org.jackaudio.Configure.GetParameterValue(QStringList parameter, QDBusVariant& default, QDBusVariant& value)
method QDBusRawType::a(ysss) org.jackaudio.Configure.GetParametersInfo(QStringList parent)
method bool org.jackaudio.Configure.ReadContainer(QStringList parent, QStringList& children)
method void org.jackaudio.Configure.ResetParameterValue(QStringList parameter)
method void org.jackaudio.Configure.SetParameterValue(QStringList parameter, QDBusVariant value)
signal void org.jackaudio.JackPatchbay.ClientAppeared(qulonglong new_graph_version, qulonglong client_id, QString client_name)
signal void org.jackaudio.JackPatchbay.ClientDisappeared(qulonglong new_graph_version, qulonglong client_id, QString client_name)
method void org.jackaudio.JackPatchbay.ConnectPortsByID(qulonglong port1_id, qulonglong port2_id)
method void org.jackaudio.JackPatchbay.ConnectPortsByName(QString client1_name, QString port1_name, QString client2_name, QString port2_name)
method void org.jackaudio.JackPatchbay.DisconnectPortsByConnectionID(qulonglong connection_id)
method void org.jackaudio.JackPatchbay.DisconnectPortsByID(qulonglong port1_id, qulonglong port2_id)
method void org.jackaudio.JackPatchbay.DisconnectPortsByName(QString client1_name, QString port1_name, QString client2_name, QString port2_name)
method QStringList org.jackaudio.JackPatchbay.GetAllPorts()
method qlonglong org.jackaudio.JackPatchbay.GetClientPID(qulonglong client_id)
method qulonglong org.jackaudio.JackPatchbay.GetGraph(qulonglong known_graph_version, QDBusRawType::a(tsa(tsuu clients_and_ports)
signal void org.jackaudio.JackPatchbay.GraphChanged(qulonglong new_graph_version)
signal void org.jackaudio.JackPatchbay.PortAppeared(qulonglong new_graph_version, qulonglong client_id, QString client_name, qulonglong port_id, QString port_name, uint port_flags, uint port_type)
signal void org.jackaudio.JackPatchbay.PortDisappeared(qulonglong new_graph_version, qulonglong client_id, QString client_name, qulonglong port_id, QString port_name)
signal void org.jackaudio.JackPatchbay.PortRenamed(qulonglong new_graph_version, qulonglong port_id, qulonglong client_id, QString client_name, QString port_old_name, QString port_new_name)
signal void org.jackaudio.JackPatchbay.PortsConnected(qulonglong new_graph_version, qulonglong client1_id, QString client1_name, qulonglong port1_id, QString port1_name, qulonglong client2_id, QString client2_name, qulonglong port2_id, QString port2_name, qulonglong connection_id)
signal void org.jackaudio.JackPatchbay.PortsDisconnected(qulonglong new_graph_version, qulonglong client1_id, QString client1_name, qulonglong port1_id, QString port1_name, qulonglong client2_id, QString client2_name, qulonglong port2_id, QString port2_name, qulonglong connection_id)
method QString org.jackaudio.SessionManager.GetClientNameByUuid(QString uuid)
method uint org.jackaudio.SessionManager.GetState(QString& target)
method QString org.jackaudio.SessionManager.GetUuidForClientName(QString name)
method bool org.jackaudio.SessionManager.HasSessionCallback(QString client_name)
method QDBusRawType::a(sssu) org.jackaudio.SessionManager.Notify(bool queue, QString target, uint type, QString path)
method void org.jackaudio.SessionManager.ReserveClientName(QString name, QString uuid)
signal void org.jackaudio.SessionManager.StateChanged(uint type, QString target)


Utilizando estos métodos podemos obtener mucha información útil sobre jack:
Alguien escribió:
$ qdbus org.jackaudio.service /org/jackaudio/Controller IsStarted
true
$ qdbus org.jackaudio.service /org/jackaudio/Controller GetLatency
23.2199535369873
$ qdbus org.jackaudio.service /org/jackaudio/Controller GetSampleRate
44100

Esta información puede ser muy útil para los programas hechos con jack dbus.

También podemos listar los puertos disponibles (no tengo claro si es posible obtener un listado separado del puertos de audio y puertos midi pero en el ejemplo aparece todo revuelto):
Alguien escribió:
$ qdbus org.jackaudio.service /org/jackaudio/Controller GetAllPorts
system:capture_1
system:capture_2
system:playback_1
system:playback_2
system:midi_capture_1
system:midi_playback_1
PulseAudio JACK Sink:front-left
PulseAudio JACK Sink:front-right
PulseAudio JACK Source:front-left
PulseAudio JACK Source:front-right
LinuxSampler:midi_in_0
LinuxSampler:0
LinuxSampler:1


y finalmente, por supuesto, conectamos dos puertos, Linuxsampler con System:
Alguien escribió:
dbus-send --type=method_call --dest=org.jackaudio.service /org/jackaudio/Controller org.jackaudio.JackPatchbay.ConnectPortsByName string:'LinuxSampler' string:'0' string:'system' string:'playback_1'


Bueno, este es un tema que me ha intrigado por mucho tiempo, aunque no le veo mucha utilidad (por lo menos no para el uso doméstico) si puede ayudar a los que quieran incursionar en esto de dbus y jack que es muy interesante.

Saludos y espero que les haya servido este minitutorial.
Subir
Irwin J. Cespedes
#2 por Irwin J. Cespedes el 31/05/2012
¡Demonios veguita! ¡Esto está bastante friki! :cuernos:

Yo si le veo alguna utilidad. Por ejemplo, supon quieres hacer un Sampler con una maquina aparte. Usas una distro sin GUI, la instalas, te haces un buen script para arrancar a JACK mediante DBUS y que de paso te abra LinuxSampler y a la vez LS abra un SF2 como el Crisis, y lo puedas controlar desde tu DAW nativo mediante MIDI.

Algo bastante jalado del pelo, pero me suena a una aplicación dentro de lo razonable (Podríamos entrar en debate de que otras cosas pueden automatizar este tipo de scripts) :susto:

En fin, buen trabajo, y ojalá que Mr. Capella arregle a QJACKCTL o que Paul Davis toquetee a jackd para que no se pongan tontos por el mentao' error de DBus que no deja cerrar a Jack.

¡Buen trabajo y saludos! Imagen no disponible
Subir
anecochea
#3 por anecochea el 02/06/2012
Sí yo estaba pensando en hacer algo que me permita cambiar más rápido de sintetizador cuando toco teclado, por ejemplo usando una combinación de teclas, me encanta el estilo de patchbay como qjackctl o Patchage, pero a veces es algo difícil cambiar rápido de sintetizador, habrá que experimentar.
Subir
Hilos similares
Nuevo post

Regístrate o para poder postear en este hilo