miércoles, 26 de mayo de 2010

Cómo medir la latencia real del sistema jack-hardware de audio

###################################
Notas de revisiones:
Revisión 0: 12 junio 2010. Publicado.
Revisión 1: 16 junio 2010. Añadidos créditos.
###################################


En la anterior entrada vimos cómo configurar el script rtirq para que nos levante automáticamente la prioridad de la tarjeta de audio (y de otros "kernel threads" importantes para el trabajo con MIDI). De esta forma, podemos conseguir en jack latencias teóricas asombrosamente bajas sin recibir xruns.

Con esto y M-audio Audiophile 2496 (PCI), consigo mantener jack (antes de lanzar ninguna aplicación, eso sí) funcionando durante un buen rato con 0 xruns a 96000 Hz, 16 cuadros por periodo y 2 periodos por buffer, con un consumo de CPU de alrededor de 20 % según marca el display de Jack Control. Sólo el conseguir que jack llegue a arrancar con estos parámetros es ya una señal de que tenemos un sistema al menos aceptablemente bien ajustado para el trabajo con audio en tiempo real, a baja latencia y libre de xruns.

El valor de latencia que aparece en el setup de qjackctl (abajo a la derecha) es la latencia de bucle completo (entrada + salida) calculada a partir de la fórmula:

(p·n / r) x 1000

Donde p es el valor de cuadros por periodo, n son los periodos por buffer y r la frecuencia de muestreo. Se multiplica por 1000 para que el resultado final salga en milisegundos.

Con p=16, n=2 y r = 96000, tenemos una latencia calculada de 0,333 ms.

¿Significa esto que si arrancamos jack con estos parámetros, conectamos virtualmente en jack el capture_1 al playback_1 y conectamos físicamente una fuente de sonido (por ejemplo, una guitarra) a la primera entrada analógica, habrá un "retardo" de 0,333 ms desde que pulsamos una cuerda hasta que escuchamos el sonido por los altavoces?

No. La indicación de jack no es una medida real de latencia. Para medir la latencia real de bucle completo podemos usar una herramienta llamada jack_delay o jdelay. Copio la descripción original:

"This is a small command line JACK app you can use to measure the latency of your sound card. It uses a phase measurements on a set of tones to measure the delay from the output to the input. Accuracy is about 1/1000 of a sample".

Instalación...

Está en los repositorios de Debian y ubuntu, con el nombre "jdelay".

Sin embargo, mejor compilar para obtener la última versión ya que en ésta aparece el valor de la latencia en milisegundos, no solamente en cuadros como probablemente encontraremos si instalamos el paquete. Tampoco pasa nada, pues podemos calcular la latencia en milisegundos diviendo los cuadros entre la frecuencia a la que esté trabajando jack.

Podemos descargar las fuentes desde:

http://www.kokkinizita.net/linuxaudio/downloads/index.html

La compilación es sencilla. Creo que sólo hacen falta las librerías de desarrollo de alsa y de jack, libasound2-dev y libjack-dev.


Uso

Advertencia: Hacer esto con el volumen de vuestro equipo de música completamente a cero. Si os confundís y conectáis la salida de jack_delay a los system_playbacks, el ruido es muy desagradable!

Si habéis compilado, el comando es "jack_delay". Si habéis instalado el paquete, "jdelay" (creo).

La salida de jack_delay se conecta a través de jack al system:playback_1 que representa la primera salida analógica. Desde ésta llevamos un cable a la primera entrada analógica que en jack aparece como system:capture_1, la cual conectamos a través de jack a la entrada de jack_delay, cerrando el bucle. En el pantallazo lo vemos más claro. La línea roja gruesa representa el cable físico.



En la salida de terminal de jack_delay, observamos que hay diferencia entre la latencia calculada y la latencia real del sistema hardware-software (tarjeta de audio + alsa-jack). Por ejemplo con:

p = 64
n = 2
r = 48000

tengo una latencia de 188,6 cuadros, que es mayor que la teórica 128 (64 x 2). En milisegundos, el valor resulta de 3,93 frente al 2,67 calculado. Esa latencia añadida es la que ocurre en los convertidores DA y AD.

No es buena idea llevar el sistema a la menor latencia posible en todas las circunstancias. De hecho, es muy mala idea. Cuando estemos editando, mezclando y masterizando subir los cuadros por periodo.

Utilizar un valor de cuadros por periodo bajo solamente cuando sea necesario. Por ejemplo, para capturar audio mientras hacemos monitorización por software.

Créditos

Jack_delay es una utilidad escrita por Fons Adriaensen, ingeniero de sonido y desarrollador de excelentes herramientas de software para Linux.
http://www.kokkinizita.net/linuxaudio/

7 comentarios:

  1. Excelente post, y no es el único.

    Todavía no me he pasado totalmente al audio en Linux, pero cada vez tengo más ganas.

    Enhorabuena por el sitio y ya nos veremos, hasta pronto!

    ResponderEliminar
  2. Gracias por todo amigo Pablo, sigues subiendo el nivel del audio en linux a un nivel espectacular.
    Salut.

    ResponderEliminar
  3. Gracias a los dos por los comentarios. Xavi, cuánto tiempo. Un abrazo, Pablo.

    ResponderEliminar
  4. Otro buen tutorial para optimizar el audio en GNU/Linux, complementando al anterior.

    Se da la casualidad de que dispongo de una M-Audio Fast Track. Gran marca M-Audio, de enchufar y listo. Salvo estas optimizaciones, por supuesto.

    Oye, 3 milisegundos está mucho mejor que bien, ¿eh? ¿Y dices que no te da fallos? ¿Y a esa velocidad de muestreo tan alta?

    Cuando acabe el álbum que traigo entre manos (en realidad son dos, contando lo que estoy haciendo con un amigo) lo pruebo. Me gustaría conocer la latencia real de mi sistema.

    Pero ahora no tengo tiempo apenas para experimentar y probar cosas de estas, así que, de momento, a la carpeta de "pendientes" de mis marcadores.

    ¡Ah! Completamente de acuerdo en subir la latencia en fases de mezcla y mastering. ¿Para qué latencias bajas entonces, y esto va también para usuarios de Mac y Windows? La latencia baja va bien para monitorizar en tiempo real ese ampli virtual de guitarra mientras tocas (Amplitube, Vandall o Rakarrack, por ejemplo), pero una vez grabado no tiene sentido hacer sudar innecesariamente la máquina.

    Voy a estar un tiempo largo, quizá meses, sin postear, Pablo. Tampoco me pasaré a comentar en vuestros blogs, así que aprovecho para decir hasta pronto, y que ya avisaré cuando me vuelva a conectar con más asiduidad.

    Lo mismo te digo, Negro de Saliceta, ya que te he visto por aquí.

    Un cordial saludo.

    ResponderEliminar
  5. ¡Te echaremos de menos José!
    Bueno, a 96 kHz no la uso nunca y no he hecho pruebas reales pero estoy seguro que se pueden conseguir latencias muy bajas. Normalmente uso 48 kHz, 64 c/p y 2 p/b para grabar con un ampli virtual pero en realidad no necesito ir tan lejos. Con 512 c/p y 2 p/b (latencia teórica en jack de 21,3 ms) aún no tengo problema. Lo noto bastante al subir a 1024 (unos 44 ms) pero aún puedo disfrutar. A 2048 (unos 90 ms) la latencia para tocar la guitarra se hace insufrible para mí. Aquí no cuento con la latencia introducida por el procesado del ampli virtual que ahora mismo no sé cómo estimar.
    Sí, la gestión de recursos tiene más que ver con la termodinámica que con un SO concreto. Lo importante para mí es que jack es muy capaz y con una buena tarjeta de audio (y hardware al que va conectada ésta) y un linux bien configurado (¡que no es tan difícil!) se pueden hacer maravillas.

    Hasta pronto


    laro, depende de muchos factores, empezando por el hardware. Ya harás las pruebas y nos comentas.

    ResponderEliminar
  6. Hey, espero que me contestes, pero veamos:

    Con el paquete jdelay corriendo en consola tengo el siguiente mensaje: signal below threshol

    De ahi hago las conexiones en jack, lo del cable rojo no me queda claro pero bueno la cuestion es que no pasa nada en consola, el mensaje no cambia. No se que estoy haciendo mal.

    Abrazos.

    ResponderEliminar
  7. Hola,

    Tienes que cerrar el bucle conectando la salida y la entrada de tu tarjeta de audio por medio de un cable (cable real, no software).

    ResponderEliminar