El post que buscas se encuentra eliminado, pero este también te puede interesar

Configura y optimiza Linux para audio y MIDI

Anuncios

El sistema de audio y MIDI

En un sistema de audio y MIDI típico basado en Linux encontramos varios componentes clave:

* JACK, el kit de conexiones de audio. Facilita servicios de audio y por supuesto utiliza la tarjeta de sonido. La IRQ de la tarjeta de sonido requiere un tratamiemto especial —es decir, una alta prioridad— para no ser interrumpida por otras cargas del sistema —el disco duro o la red—. JACK es la opción favorita para este trabajo dado que permite conectar las aplicaciones de audio las unas con las otras. Además está diseñado para el trabajo a tiempo real desde el primer día. Con un sistema correctamente configurado pueden lograrse latencias ridículamente bajas, p.ej. tamaños de buffer de 8 ó 16 muestras a 48 KHz.
* ALSA, facilitando servicios de audio a JACK y el acceso al MIDI vía alsa-seq.
* Algún secuenciador MIDI como rosegarden, muse o seq24 que utilice JACK y alsa-seq.
* Algunos sintetizadores software —al final, clientes JACK— manejados por el secuenciador MIDI
* Más hardware que precisa de una IRQ para funcionar —red, disco duro, etc.—
* El resto del software, como el gestor de ventanas, el escritorio y otras utilidades.

Cualquier kernel -rt en combinación con realtime lsm o rt_limits facilita al usuario herramientas que le permiten un trabajo cómodo que asegura:

* Operación de audio sin problemas, y con «sin problemas» me refiero a sin problemas. Por ejemplo, puedo fácilmente compilar un kernel mientras trabajo con audio a 32 muestras por buffer.
* Sincronización MIDI exacta.

Claro está que habrá que ajustar el sistema para obtener el mejor resultado. Podría ser necesario llegar a modificar algunas aplicaciones.

Configuración de audio

Podemos simplificar y decir que cuanto más alta sea la prioridad de una tarea más posible es que se ejecute sin molestias. Con un kernel -rt se tiene la posibilidad de que ciertos manejadores de IRQ tengan menos prioridad que aplicaciones que corren en el espacio de usuario. Es posible, por ejemplo, correr jackd con una prioridad mayor que la de cualquier manejador de IRQ que podría interrumpir el trabajo con audio, como el disco duro o la red. Es necesario el parámetro -P de jackd para esto.

En un kernel -rt, por defecto todos los manejadores de IRQ tienen prioridades entre 40 y 60, así que hacer que jackd se ejecute con una prioridad de 70 parece una buena elección.

jackd -R -P 70 -d alsa ...


Sólo que si queremos que el manejador de la IRQ de la tarjeta de sonido tenga una prioridad más alta que jackd, dado que la IRQ de la tarjeta de sonido es al final la que gobierna el funcionamiento de JACK. Utilizamos así la utilidad chrt para cambiar esto. En mi sistema la tarjeta de sonido tiene la IRQ 4, comprueba /proc/interrupts en tu máquina para averiguar la tuya.

chrt -f -p 82 `pidof "IRQ-4"`


—N. del T.; Comprueba las distintas prioridades asignadas así:—

top -b -H -n 1 | grep -i irq | sort -n -k3


Una prioridad de 82 está bien por encima de la concedida a jackd. Dado que jackd ejecuta hilos además de su bucle principal, es necesario vigilar esto. Por ejemplo, implementa un watchdog que se ejecuta a una prioridad 10 superior a la del bucle principal. Es decir, a 80 en nuestro caso. Los hilos de proceso de cliente, en cambio, corren con una prioridad 1 inferior a la del bucle principal, 69 en nuestro caso.

La parte audio de nuestro sistema queda cubierta. Con esta configuración consigo operar con tamaños de buffer ridículamente bajos con JACK y mi M-Audio Delta 66 —hasta 8 muestras por periodo, reconociendo algún problema con el cambio de contextos forzando tanto mi sistema— Y ahora, ¿qué pasa con MIDI? ¿Cómo lo hacemos funcionar aquí?

Configuración MIDI

Tenemos que saber una cosa o dos sobre cómo la planificación a tiempo real funciona para afinar esta parte. La clase de planificación utilizada por la mayor parte de aplicaciones de audio es SCHED_FIFO. Se trata de una clase especial con niveles de prioridad estáticos de 1 a 99 y que garantiza que las tareas que la utilizan pueden conservar la CPU tanto tiempo como requieran, siempre que otra tarea SCHED_FIFO de mayor prioridad no la reclame. Por supuesto esto significa que un programa lo suficientemente puñetero puede bloquear el sistema simplemente acaparando toda la CPU siempre que no haya otra tarea con una prioridad mayor que pase por encima. Así que las tareas que tienen más prioridad ahora en nuestro sistema son los hilos de jackd y el manejador de la IRQ de la tarjeta de sonido.

El procesado de audio se realiza por lotes y para ilustrarlo permítaseme asumir que utilizamos un tamaño de buffer muy grande, digamos de 1 segundo —no sé si alguna tarjeta de sonido permite un buffer de este tamaño, pero para ilustrar el argumento supongamos que sí—. Se trata de 48.000 muestras a 48 KHz. Asúmase también que los clientes JACK están cargando realmente el sistema. Por ejemplo que el indicador DSP de jackd muestra un 50%. Esto significa que cada segundo el sistema completo se detiene para que jackd y sus clientes se tomen ese medio segundo para realizar sus procesos. Es fácil adivinar que el efecto en la sincronización MIDI va a ser terrible.

En realidad MIDI necesita más «tiempo real» que el audio. El audio se procesa en lotes de tamaño respetable —entre 1 y 50 ms dependiendo del tamaño de buffer utilizado—. Pero cuando un secuenciador MIDI necesita enviar un evento a un puerto, debe hacerlo con garantías de que llegará a tiempo a su destino —hay una excepción derivada de la implementación del secuenciador MIDI en ALSA, el cual permite aplazar eventos hasta un tiempo posterior, y de la que se derivan los problemas de ALSA con el MIDI—. El procesado MIDI, en cambio, es ligero comparado con el de audio. El bucle principal de un secuenciador MIDI necesita ejecutarse muchas veces por segundo para ser capaz de procesar eventos MIDI con una resolución lo suficientemente detallada. Así que la parte MIDI de un secuenciador debería correr con una prioridad mayor que jackd. La interfaz alsa-seq permite que los eventos MIDI sean aplazados para ser entregados en un momento preciso, lo que aligera el requisito de «debo enviarlo ahora mismo». Pero se trata de una funcionalidad compleja de gestionar y no demasiados programadores la utilizan. Así que tiene mucho más sencillo configurar el sistema para que los datos MIDI tengan una entrega inmediata.

Hay distintas fuentes de sincronización utilizadas por los secuenciadores MIDI en un sistema Linux. Las más comunes son:

RTC

El reloj en tiempo real que todo PC tiene. Corre a una frecuencia programable, p.ej. de 1.024 Hz y permite a una aplicación ser ejecutada muy a menudo y muy regularmente. Para que la sincronización basada en RTC funcione bien, el manejador de la IRQ del RTC —la IRQ 8 en un sistema XT-PIC, consúltese /proc/interrupts— necesita una prioridad superior a la de jackd y a la del resto de aplicaciones del sistema. 98 es un buen valor.

chrt -f -p 98 `pidof "IRQ-8"`


Aún si no se utiliza el RTC, esta configuración no hará ningún daño. Si se quiere que los usuarios ordinarios puedan hacer uso del RTC a una frecuencia razonablemente alta, hay que asegurarse de que:

/proc/sys/dev/rtc/max-user-freq


Está configurado a 8192. Puede hacerse ejecutando como root:

echo 8192 > /proc/sys/dev/rtc/max-user-freq


—N. del T.; Es posible llevar esta configuración a /etc/sysctl.conf, consúltese la ayuda.—

Es posible por supuesto visualizar el valor actual:

cat /proc/sys/dev/rtc/max-user-freq


Temporizador basado en sleep()

En este caso la aplicación corre repetidamente poniéndose a sí misma a dormir por cortos intervalos. Luego mide cuánto tiempo durmió para ser capaz de sincronizar correctamente. No sé exactamente como sleep() o sus derivadas como nanosleep() o usleep() están exactamente implementadas en Linux, así que me permito una adivinanza.

Cuando una tarea echa a dormir en realidad le dice al planificador que libera la CPU y que no quiere volver a ser ejecutada hasta que el tiempo de sueño haya vencido. El temporizador del sistema es una interrupción especial de temporización en todo sistema PC que corre a una frecuencia de 250 Hz en la configuración por defecto de un kernel Linux. Este temporizador del sistema ejecuta el bucle principal de ejecución de un kernel Linux, a saber, el planificador. Así que cuando sólo hay un temporizador disponible en el sistema, el tiempo más breve que una aplicación puede dormir son 4 ms —1/250 seg—. La granularidad es grande, así que cabe aconsejar cambiar la frecuencia por defecto del temporizador del sistema de 250 Hz a 1.000 Hz, lo que facilita una resolución de milisegundo a sleep(). Presúmase que se trata de una configuración correcta, que sólo costará un mínimo de carga adicional en el sistema.

Dado que este temporizador del sistema siempre corre a la máxima prioridad SCHED_FIFO en los kernel -rt actuales, no es necesaria ninguna configuración extra.

¡BZZZZT ERROR! Podrías tener que dar a algunos hilos de temporización también una alta prioridad para que sleep() funcione correctamente. El más importante aquí es softirq-timer/0, así que dale también un 99.

¡BZZZZZZZT ERROR OTRA VEZ! Esto se aplicaría sólo para un kernel habiendo sido compilado sin el soporte al temporizador de alta resolución. Espero aclarar este punto en algún momento en más detalle preguntando directamente a Ingo Molnar. Si en tu configuración el temporizador de alta resolución ha sido activado, no debería ser necesario darle a softirq-timer/0 una prioridad tan alta.

En realidad, actualmente parece que establecer esa alta prioridad a softirq-timer/0 daña el rendimiento del sistema. Así que de momento recomiendo configurar el temporizador de alta resolución en el kernel y dejar en paz a softirq-timer/0.

Otras fuentes de sincronización

¿Los temporizadores POSIX de alta resolución?

Hilos MIDI en aplicaciones MIDI


Nuestras fuentes de sincronización ya han sido establecidas. ¿Qué pasa ahora con las aplicaciones que las utilizan? Establecer una alta prioridad para la interrupción del reloj no es todo lo que se necesita. Las aplicaciones corriendo en el espacio de usuario deben utilizar dichas interrupciones directa o indirectamente, y también necesitan correr con altas prioridades. Idealmente por encima de la de jackd y el resto de material de audio.

Sintetizadores software

Habitualmente tienen un hilo de ejecución que recibe eventos MIDI, les añade una marca temporal —p.ej. mediante jack_frametime()— y los mete en una cola —idealmente un ringbuffer sin lock— donde las llamadas a audio_process() los van consumiendo. La llamada a process() puede determinar exactamente dónde dentro del periodo deben generarse los datos de audio correspondientes utilizando el método jack_last_frametime() de JACK —un método sencillo; añádase un periodo a la marca temporal de los eventos MIDI y después réstese el jack_last_frametime de la cuenta. La diferencia resultante es el desplazamiento dentro de el periodo que se está procesando. El hilo de recepción y marca temporal MIDI necesita correr a una prioridad más alta que jackd y que todos los procesos de audio. 90 es por ejemplo una elección razonable.

He escrito un pequeño sintetizador software que evalúa numéricamente la ecuación de onda que utiliza este esquema, y que funciona realmente bien.

ughsynth-0.0.5.tgz

Téngase cuidado sin embargo con la cantidad de CPU que utiliza —hasta un 50% en mi Athlon a 1,2 GHz—.

Secuenciadores MIDI

Generalmente tienen al menos un hilo de ejecución para manejar su sincronización MIDI. Algunos usan el RTC, otros se basan en sleep(). El único que conozco que permite establecer su prioridad en tiempo real es seq24 pero, hasta donde sé, esta prioridad está a pelo en el código fuente. Así que para ajustarla tendrás que remangarte.

No sé demasiado sobre el resto de secuenciadores MIDI ni de cómo manejan esta cuestión. Rosegarden por ejemplo facilita dos opciones diferentes para su fuente de sincronización —RTC y reloj del sistema basado en sleep()— pero no he encontrado la forma de obtener más detalles. Debería ser posible acceder a esta configuración utilizando la interfaz de usuario, lo que sería lo ideal.


Fuente: http://www.linuxav.net/index.php/2009/01/configura-y-optimiza-linux-para-audio-y-midi/

Anuncios

3 comentarios - Configura y optimiza Linux para audio y MIDI

@eniothesexmachine +1
muy bueno, no me anime por que son muchas cosas, como uso fedora estan los repositorios de planet ccrma que tiene el kernel de baja latencia incluido, y si quiero puedo elegir el kernel real time, y si no, selecciono el comun, asi evito problemas de compatibilidad con algunos programas que se taran con el RT, buen aporte.
@autoblindaje
soy músico electrónico aficionado y uso mucho la PC para mis creaciones. me interesó siempre ver qué posibilidades de trabajo con audio, síntesis y secuenciación podía tener bajo linux, pero no encuentro la más mínima guía para comenzar y todas las explicaciones de uso y configuración me parecen chino avanzado para antiterrorismo. ¿alguien sabe dónde puedo encontrar una buena guía para principiantes con ejemplos de software y muestras de configuración de hardware (tengo una placa externa TASCAM por usb)? ¡muchas gracias!