viernes, 17 de diciembre de 2010

Configuración del servidor de audio Jack. Segunda parte

#########################
Notas de revisiones:
Rev 0: 19 diciembre 2010. Publicado.
Rev 1: 25 mayo 2011. Edición de mantenimiento.

#########################


Segunda parte. Dispositivos de entrada y de salida. Jack sobre varias tarjetas de audio

Si estás perdido en la tarea de configurar el servidor de audio jack, no empieces por aquí. Lee antes la primera y más importante parte.

Lo normal es que jack trabaje sobre una única tarjeta (el "interfaz") en la cual tendremos entradas y salidas suficientes para capturar y reproducir sonido. Sin embargo, se puede configurar jack para que utilice diferentes dispositivos de entrada y de salida.

También presentamos las utilidades alsa_in y alsa_out.

En las faq de jackaudio hay escrito algo sobre esto, yo intentaré elaborarlo un poquito más aun a riesgo de meter la pata.

Tarjetas y dispositivos

Alsa maneja los conceptos de "Tarjeta" (Card), "Dispositivo" (Device) y "Subdispositivo" (Subdevice). Cada tarjeta puede tener varios "dispositivos" y éstos a su vez, varios "subdispositivos". Jack necesita saber qué tarjeta y qué dispositivo usar así que dejamos de lado el "subdispositivo" (menos mal).

En general, una tarjeta soportada por alsa, se denomina numéricamente "hw:x,y", donde "x" es el número de tarjeta e "y" es el número de dispositivo, comenzando ambos desde cero. Muchas tarjetas tienen un dispositivo único y no hace falta especificarlo. Así, hw:0 es lo mismo que hw:0,0. Sin embargo hay otras tarjetas que tienen varios dispositivos, típicamente, las tarjetas "de consumo". Veamos esta imagen:



"arecord -l" muestra las tarjetas y dispositivos que sirven para captura y "aplay -l" los que se pueden usar para reproducción (he filtrado las líneas que contienen la palabra "subdispositivo"). En cada tarjeta puede haber dispositivos únicamente de captura, únicamente de reproducción, o dúplex. Los dispositivos dúplex (capaces de captura y reproducción simultánea) aparecen en la salida de ambos comandos.

Veis que la tarjeta 0, en este caso la M Audio Audiophile 24/96 (hw:M2496) nos lo pone fácil; sólo tiene un dispositivo y es válido tanto para captura como para reproducción.

La tarjeta 1 es la integrada, hw:Intel. Tiene dos dispositivos, uno para los puertos analógicos y otro para el puerto digital. Ambos son utilizables tanto para captura como para reproducción.

La tarjeta 2 es una tarjeta virtual. Paso palabra.

Con la tarjeta 3, la mítica SB Live!, la cosa se lía un poco. Si elegimos la interfaz "hw:Live" la cosa va bien pero nos encontramos con que sólo tenemos dos puertos de captura y dos puertos de reproducción. hw:Live es equivalente a hw:Live,0 y por tanto se usa el dispositivo que corresponde a "ADC Capture/Standard PCM Playback", que, por lo que se ve, enseña solamente estos 2 + 2 puertos.

¿Qué pasa con el resto de salidas del sistema surround? Pues que están en otro "dispositivo".

Para acceder a estos puertos podemos usar "hw:Live,0" para captura (es decir, "dispositivo de entrada" y "hw:Live,3" para reproducción (dispositivo de salida). Eso sí, tendremos que ir descubriendo qué "puerto escribible" de jack corresponde a qué salida física y, por supuesto, el mezclador interno y los niveles de los canales deberán de estar configurados correctamente en alsamixer.

En el pantallazo se puede observar cómo el menú desplegable en los dispositivos de entrada y salida se corresponden con las salidas de arecord -l y aplay -l respectivamente.



Por supuesto, también podemos intentar usar dispositivos de entrada y salida de tarjetas diferentes, pero no es muy recomendable. Para eso es mejor usar alsa_in y alsa_out.

alsa_in y alsa_out


Ejemplo de uso:

Jack está ejecutándose sobre el interfaz hw:M2496 pero nos vendría bien un canal estéreo de la SB Live! para monitorización. Podríamos usar:

alsa_out -jSBlive -dhw:Live,0

La opción -j es opcional. Ver: man alsa_out

Otras opciones

En el archivo ~/.asoundrc podemos crear dispositivos virtuales aunque esto es algo que supera mis conocimientos y mi experiencia. Ver el clásico "el cheapo howto" http://quicktoots.linuxaudio.org/toots/el-cheapo/ y la documentación de alsa para algunos ejemplos.

sábado, 4 de diciembre de 2010

Configuración del servidor de audio Jack. Primera parte

#########################
Notas de revisiones:
Rev 0: diciembre 2010. Publicado.
Rev 1: 17 diciembre 2010. Actualizado.
Rev 2. 22 enero 2011. Retocado texto de introducción.
Rev 3. 27 enero 2011. Añadidas referencias y enlaces (al final).
REv 4. 24 mayo 2011. Añadidas notas sobre el soporte del hardware y página de referencia de Jack1 vs Jack2

#########################



Primera parte. La ruta del servidor, el driver, el interfaz y el modo realtime



Introducción


Como es sabido, el servidor o demonio jackd permite baja latencia y una gran flexibilidad en las conexiones entre los puertos de audio y midi de sus clientes. Su configuración es también muy flexible y depende por completo de nuestro hardware y software de bajo nivel. NO hay una configuración universal. Por eso es importante entender al menos los conceptos básicos.

Hay que tener en cuenta que Jack se comunica directamente con el driver de la tarjeta de audio que nosotros elijamos. Además, necesita que el sistema operativo le deje hacer "sus cosas".

Eso sí, si conseguimos que el servidor Jack esté a gusto en nuestro sistema habremos recorrido un buen trecho del camino hacia el objetivo de hacer música con Linux.

qjackctl, o Jack Control es una interfaz gráfica que, entre otras cosas, nos permite configurar el servidor jackd, a través del botón Setup, pestaña "Configuraciones".

Al que le gusta experimentar sólo un consejo: Los valores por defecto son lo más universales posible, así que, si no funciona a la primera es buena idea hacer un solo cambio cada vez y volver a probar en lugar de poner todo en duda y querer entenderlo a la primera. En muchas ocasiones, un pequeño cambio arregla las cosas.

Como dijo Einstein, "Haz las cosas lo más simple posible". Aunque después añade: "Pero no más simple". Supongo que esto último fue lo que inspiró al gran Rui Nuno Capela para meter en una única ventana de configuración lo importante y lo menos importante, lo esencial y lo inútil, pero eso sí, todos los argumentos posibles que se le pueden pasar a jackd (bueno, casi todos).

Así que para simplificar, en esta serie de entradas vamos a ver la configuración de jack con sus opciones y parámetros en orden (no estricto) de importancia. Como dijo el otro Jack (el destripador), vamos por partes.

La ventana principal de qjackctl, indicando que el servidor jackd está iniciado. Ojo, "Detenido" se refiere al "transporte de jack", el cual sirve para sincronizar diferentes aplicaciones con un transporte común. El transporte de jack no se trata en esta entrada.


Jack1 y Jack2


Antes de seguir adelante, una explicación que considero importante. Jack1 es el jack original, escrito en C y desarrollado por Paul Davies. Stephan Letz reescribió jack en otro lenguaje de programación (C++), para soportar multiprocesadores. Por ello, jack2 es también llamado jackmp. Ambas implementaciones de jack tratan de mantenerse compatibles en sus argumentos de línea de comandos (aunque hay alguna pequeña diferencia como veremos) y qjackctl sirve perfectamente para ambos.

En todo caso, se debe tener en cuenta que:

- jack2 no es un reemplazo de jack1. Simplemente es diferente. Ambos se desarrollan en paralelo.

- Aunque jack2 tiene cosas buenas que jack1 no tiene, en general, jack1 está más probado y tiende a ser más robusto, especialmente con ardour.

- Normalmente, no podemos tener instalados los dos jacks al mismo tiempo. Tenemos que elegir. En ubuntu, hasta lucid lynx tendremos jack1 por defecto y, a partir de maverick (10.10 y posteriores), jack2. Podemos cambiar a jack1 instalando el paquete "jackd1" (que, por supuesto, desinstalará jackd2).

- Para saber cuál de los dos jacks tenemos instalado usamos el comando: "jackd -V". Las versiones que comienzan por 0, por ejemplo, 0.119.0, son jack1. Las que comienzan por 1, por ejempo 1.9.6, son jack2.

En la sección "Para saber más" hay una explicación más técnica y mejor informada acerca de las diferencias entre jack1 y jack2.

La ruta del servidor, el driver, el interfaz y el modo realtime



1. Ruta del servidor

Es el comando básico con el que lanzamos el servidor jack. Normalmente, la ruta completa del ejecutable es /usr/bin/jackd aunque también sirve jackd a secas.

Modo síncrono o asíncrono en jack2

jack2 funciona por defecto en modo asíncrono. Me parece que el modo asíncrono permite conectar y desconectar clientes sin provocar xruns pero lo malo es que añade un periodo de latencia (que qjackctl no reporta). jack1 simplemente no tiene modo asíncrono así que si queremos un jack2 que se parezca a jack1 lo lanzamos en modo síncrono añadiendo "-S" (precedido de un espacio y sin las comillas) al comando jackd, es decir, /usr/bin/jackd -S


Como veis en el pantallazo en la parte de abajo a la derecha, yo tengo instalado jack1 así que no me preocupo por esto. Sin embargo, si estáis con jack2, os recomiendo que lo lancéis en modo síncrono.

2. Driver

Usaremos el driver alsa si nuestra tarjeta es PCI o USB. Si tenemos una tarjeta firewire, usaremos el driver firewire. El resto de opciones, o están obsoletas o son para otros sistemas operativos, o para tarjetas soportadas por drivers alternativos y rara vez útiles. Aquí hacemos otro inciso obligatorio....


Soporte de tarjetas de audio


El soporte de tarjetas de audio en Linux está lejos de ser ideal, por lo que es importantísimo informarse antes de comprar. No me voy a extender porque es un tema que no controlo demasiado. Solo unas ideas:

Las tarjetas firewire están soportadas por los drivers del proyecto ffado, mientras que las USB y las PCI, por el proyecto ALSA. En sus páginas oficiales, se puede ver un listado de las tarjetas soportadas. Tener en cuenta que no todas están soportadas igual de bien.

Además, no sólo hay que tener en cuenta la propia tarjeta, sino también los controladores de los puertos USB y firewire.

Lo mejor es preguntar en sus páginas oficiales o en sus listas de correos, o en su defecto, en foros de usuarios, como el de hispasonic GNU/Linux o el superforo de ardour, ambos en castellano.

En inglés, las listas de usuarios de Linux Audio, de ALSA, de ffado, el foro de linuxmusicians, el foro de ardour... Además, algunos canales de IRC en freenode.net como #ffado, #alsa, #jack, #ardour, #opensourcemusicians, #ubuntustudio, etc, son recursos de ayuda en tiempo real que, con un poco de educación, suerte y paciencia, nos pueden ahorrar mucho tiempo y quebraderos de cabeza.

Ver también What audio interfaces should I use with Ardour?

3. Interfaz

Aquí indicamos la tarjeta de audio que va a utilizar Jack. Lo mejor es identificarla por su nombre en lugar de por su número.

Una forma para saber el nombre es usando el comando "cat /proc/asound/cards". Lo vemos entre corchetes. Como podéis observar en el pantallazo, linux-alsa está viendo 4 "tarjetas"; una m-audio 2496, la hda-intel integrada, snd_aloop y un teclado midi hardware, KeyRig 49. Por supuesto, quiero que jack trabaje sobre la m-audio que se identifica como "hw:M2496" y esto es lo que escribo en el campo "Interfaz". No importa que no aparezca en el menú desplegable; en este ejemplo hw:0 es lo mismo que hw:M2496. Es mejor poner hw:M2496 porque la numeración podría cambiar en diferentes arranques del ordenador pero el nombre no.

No con todas las tarjetas es tan fácil y tan directo. En la segunda parte desarrollamos un poco más todo esto y explicamos cómo usar un dispositivo para captura y otro diferente para reproducción.

4. Tiempo real

La casilla Tiempo Real da a jack privilegios de "real-time scheduling", es decir le "da derecho" a disponer de mayor prioridad que otros procesos. Esto es necesario para que jack pueda funcionar de forma estable a baja latencia. A veces se confunde la opción realtime con la necesidad de funcionar con un kernel 'rt'. No es que no tenga nada que ver, pero no es necesario un kernel realtime (con el parche PREEMPT_RT) para poder lanzar jackd con prioridad realtime.

Para que un usuario (es decir, no el administrador del sistema) pueda arrancar jack con la opción 'RealTime' es necesario que el usuario tenga asignada "prioridad de realtime" en el archivo de configuración del sistema '/etc/security/limits.conf' o cualquier otro archivo dentro del directorio /etc/security/limits.d/. En la práctica, esto se consigue haciendo que el usuario pertenezca a un grupo (en Debian/ubuntu, típicamente el grupo 'audio') y declarando el "privilegio" para este grupo, mediante una línea como '@audio - rtprio 99'. Además, debemos añadir otra línea como '@audio - memlock xxxxxx' donde xxxxxx es un número en kbytes relativamente alto. Algunos recomiendan que sea alrededor del 75% de la memoria RAM total. Otros directamente ponen el valor 'unlimited'. Según las advertencias de jack, el valor "unlimited" es peligroso para entornos multiusuario pero para un ordenador personal de usuario único tengo entendido que es aceptable.

En Debian testing y en ubuntu a partir de lucid, la forma más sencilla de darse prioridades de rtprio y memlock unlimted es con el comando:

sudo dpkg-reconfigure -p high jackd

(esto funciona en ubuntu lucid por ejemplo). En ubuntu maverick y probablemente en debian testing y derivadas, hay que especificar jackd1 o jackd2. Por ejemplo, desde una instalación limpia de ubuntu maverick, habría que hacer:

sudo dpkg-reconfigure -p high jackd2

Después, debemos asegurarnos que estamos en el grupo audio con el comando:

groups

Y si no es así, debemos añadir nuestro usuario al grupo audio. Se puede hacer de varias formas, por ejemplo con el comando:

sudo adduser nuestro_nombre_de_usuario audio

Estos cambios requieren reiniciar el ordenador.

Antes de lanzar jack viene bien comprobar que realmente nuestro usuario tiene los privilegios rtprio y memlock. Podemos usar el comando ulimit:

ulimit -r -l

Si la respuesta es algo parecido a:

real-time priority (-r) 99
max locked memory (kbytes, -l) unlimited


ya tenemos el sistema preparado para jack en modo realtime.

Entonces, ¿Cuando es necesario un kernel realtime?

Básicamente y que yo sepa, cuando los dispositivos hardware (tarjeta de audio, controlador firewire) comparten número de IRQ con otros dispositivos. Si recibimos muchos xruns sin motivo aparente (por ejemplo, con solamente jackd activo) a una latencia no excesivamente baja (por ejemplo, con 512 cuadros por periodo) merece la pena intentarlo con el kernel rt. No olvidemos que necesitamos levantar las prioridades de estos dispositivos, lo cual lo podemos hacer de forma automática con el script rtirq. Otro motivo para instalar el kernel rt es que, incluso cuando tenemos un sistema estable con una latencia lo suficientemente baja, queramos participar en una carrera para presumir de latencia. Yo creo que la latencia, cuanta más mejor, siempre que no nos impida interactuar cómodamente, es decir, siempre que no fastidie. Recordemos que el sonido tarda 2,9 ms en viajar a un metro de distancia... A alguien le molesta la latencia real de casi 9 ms cuando se pone a tocar o a cantar a 3 metros de un monitor? Bastante más te puedes alejar y seguirás igual de bien. Claro que se puede argumentar que todo suma, así que en software, cuanta menos latencia mejor. También es verdad, pero sin pasarse...


Para saber más


FAQ de jackaudio.org
Knowing jack, por Dave Philips
Diferencias entre Jack1 y Jack2