El sonido en Linux es confuso: Clarificando Parte 2: PulseAudio

Lo que sigue es una traducción “quick and dirty” del segundo de dos excelentes artículos escritos por Colin Guthrie. Todo comenzó por mi intento de desentrañar la manera en que Linux maneja el audio por estos días. Luego dí con Colin Guthrie el encargado de la parte de sonido en Mandriva, el cual tuvo la amabilidad de responder varias preguntas, y al parecer todo esto fue un disparador para que él escribiera estos dos posts altamente recomendables, aquí va el primero (el original en inglés del segundo artículo se puede leer haciendo clic aquí):

En un artículo anterior, describí como la configuración de bajo nivel de ALSA nos permitía encaminar todas las aplicaciones usando el API ALSA via PulseAudio. En este artículo echaremos una mirada a los distintos archivos de configuracion y a las variables que controlan este lado del camino de audio. Recorreremos por lo que pasa cuando una aplicación intenta reproducir sonido.

Aplicación ALSA

En primer lugar, una aplicación usando el API ALSA intenta abrir el dispositivo “predeterminado”. Asumiendo que hemos configurado el dispositivo predeterminado para que sea el plugin de PulseAudio para ALSA, básicamente actuará como cada aplicación PulseAudio cliente. Ahora estamos dentro de la tierra de la configuración de PulseAudio.

Cliente PulseAudio

PulseAudio adopta un modelo cliente/servidor que es muy similar en principio al del sistema X11. Es el servidor que realmente hace salir el audio y la aplicación cliente que le dice al servidor que reproducir. Si bien este enfoque puede ser ineficiente, resultando en la copia de datos por todos lados, PulseAudio hace lo más que puede para asegurar que los datos que se copian y otras operaciones sujetos a latencia se mantengan a un mínimo. En el uso comón tanto de cliente y servidor corriendo en la misma máquina, PulseAudio usa SHM (Shared Memory) para asegurar que los datos enviados desde el cliente al servidor no se copian a través del cable. El núcleo del servidor PulseAudio mismo es “copia cero” que quiere decir que las referencias a los datos se difundan sin copiar los datos mismos realmente.

Lo primero que un cliente PulseAudio tiene que hacer es conectarse  a un servidor. Para hacer esto, verifica que distintas variables y archivos de configuración para determinar precisamente a cual servidor se conectará!

Inicialmente, la librería del cliente PulseAudio busca una variable de entorno PULSE_SERVER. Si la encuentra, esta variable puede definir una lista de servidores a los que el cliente debería conectarse. Estos servidores se pueden especificar como sockets UNIX locales o direcciones de nombres/IP para una conexión TCP.

Si esta variable no existe o está vacía, PulseAudio entonces verifica las propiedades X11 en la ventana raíz. Estas propiedades son bastante parecidas a variables de entorno, pero estarán disponibles remotamente si hacés SSH a otra máquina sin redireccionamiento de X11. Hablaré de esto más tarde. Podés ver una lista de PulseAudio relacionada haciendo:

xprop -root | grep PULSE

Los nombres de las variables usadas son las mismas que aquellas usadas en el entorno, de manera que PulseAudio buscará una propiedad llamada PULSE_SERVER.

Asumiendo que aun no tiene un servidor al cual conectarse todavía, PulseAudio comprobará la configuración de un servidor predeterminado en el archivo client.conf. Este archivo está ubicado en /etc/pulse/ o ~/.pulse/. Solamente se procesa un archivo client.conf. De manera que si el usuario tiene el suyo, no se procesará el del sistema en absoluto (esta es un cuestión que traté de hacer vano en PulseAudio bug #606 – llevó un tiempo para que esto se entienda como podés ver!).

Entonces hemos tratado tres maneras de encontrar un servidor. Si todavía no hemos encontrado uno, recurrimos simplemente al predeterminado – i.e. conectándose a un daemon personal y a un daemon del sistema (un daemon del sistema generalmente no se recomienda, pero está soportado para diferentes circunstancias – comúnmente sistemas embebidos). Si todavía no podemos conectarnos, el archivo client.conf puede especificar si intentaremos o no iniciar automáticamente un daemon personal. Desde PulseAudio 0.9.11, este es el comportamiento predeterminado y permite a las aplicaciones de consola funcionar directamente sin iniciar un daemon PulseAudio de antemano.

Entonces, en el improbable caso que todo falle, finalmente no seremos capaces de reproducir sonido, pero hemos hecho casi todo lo que podemos hacer para hacerlo funcionar! Para visualizar mejor esto, miremos algunos de los escenarios comunes y reveamos el proceso de arriba.

Aplicación de consola

Entonces, en una instalación predeterminada, hemos arrancado en nivel de ejecución 3 y logueado en la terminal. No definimos ninguna variable especial e iniciamos una aplicación que reproduce sonido via ALSA. Aquí está lo que pasa.

  1. La aplicación abre un dispositivo predeterminado.
  2. El plugin de PulseAudio para ALSA (como cualquier cliente PulseAudio) comprueba que hay una configuración para un servidor y no encuentra uno.
  3. Intenta conectarse a un servidor local pero falla por que no se está ejecutando.
  4. Entonces arranca un servidor PulseAudio automáticamente y entonces se conecta a él.
  5. La aplicación luego reproduce audio via las funcionaes del API de ALSA y este es finalmente reproducido por el daemon PulseAudio.
  6. La aplicación cliente termina haciendo lo suyo, y luego sale.
  7. El daemon PulseAudio permanece por ahí por un rato en caso de que otra aplicación quiera reproducir sonido en el futuro cercano.
  8. Después de un rato, el daemon PulseAudio se enoja porque nadie lo quiere y se suicida :p

Así que es eso. Es bastante simple. Tomemos otro ejemplo.

Aplicación X11

Bajo X11 las cosas son un poquito diferente, pero se siguen los mismos principios básicos.

  1. Durante la inicialización de X11, los escritorios modernos que soportan Autoinicio XDG finalmente ejecutan el script start-pulseaudio-x11. Este script asegura que el daemon PulseAudio sea reiniciado y que se carguen algunos módulos extra relacionados con X11 se carguen en él. Estos módulos aseguran que, a diferencia de una aplicación de consola, el damon PulseAudio de X11 no salga luego de un tiempo de espera inactivo – en cambio estará dando vueltas por ahí mientras la sesión X11 exista. Esto asegura que las propiedades X11 mencionadas antes se definan – las razones para eso se verán claramente en el próximo ejemplo.
  2. Cuando cualquier cliente PulseAudio (sea una aplicación ALSA via el plugin PulseAudio vía ALSA, o PulseAudio nativo) se inicia pasa por su “rutina de buscar un servidor”. Ahora detendrá este proceso cuando alcanza las propiedades de X11 y usa la información de ella y se conecta al servidor.
  3. La aplicación cliente luego reproduce sonido como antes y finalmente termina y sale.
  4. El daemon PulseAudio no sale/se mata a sí mismo mientras la sesión de X11 está todavía andando.

Entonces de nuevo, las cosas son realmente simples.

La aplicación X11 remota

Una de las cosas más prácticas de X11 es la capacidad de conectarse a otra máquina en tu red y ejecutar aplicaciones con interfaz gráfica y mostrarlas en tu pantalla local. Con PulseAudio, el sonido también se oye en la máquina local. Las conexiones remotas (por razones de seguridad) no se habilitan de manera predeterminada. Para habilitarlas, ejecutá paprefs y habilitá la opción Habilitar el acceso desde la red  a dispositivos de sonido locales. Esta es la única opción que se necesita para este ejemplo. Carga un módulo adicional en el servidor que escucha en el puerto TCP 4713 para conexiones entrantes. Obviamente, no hace falta decir que cualquier firewall en la máquina debe habilitar conexiones a este puerto!

  1. El usuario inicia una sesión X11 normal y el script start-pulseaudio-x11 asegura que las propiedades X11 sean definidas como en el ejemplo anterior.
  2. El usuario entonces se conecta a otra máquina de su red vía ssh e inicia un reproductor de audio (e.g. Rythmbox, Amarok, etc.)
  3. Aun cuando la aplicación se está ejecutando remotamente se mostrará localmente.
  4. Cuando la aplicación comience a reproducir audio, la porción cliente buscará las propiedades X11 que han sido redireccionadas a través de la conexión SSH.
  5. El cliente PulseAudio entonces se conectará por TCP al servidor PulseAudio ejecutándose en la máquina local del usuario.
  6. El usuario disfruta la imagen y el audio local que la aplicación proporciona.

Entonces, como podés ver, el uso de las propiedades nos ha permitido subirnos a caballito del redireccionamiento X11. No es una conexión totalmente limpia ya que bajo SSH los datos de X11 realmente irán por un túnel por un enlace seguro manejado por SSH mismo, en cambio todo lo que estamos haciendo es decirle al cliente PulseAudio donde conectarse directamente, por fuera de cualquier túnel SSH. Esto significa que si bien la visualización puede funcionar sobre un systema NATeado, el sonido no lo hará. Esto es claramente tratado, pero tendríamos que enseñarle a SSH acerca de PulseAudio para que esto funcione. La razón por la que funciona para X11 es porque sabe de aquél, y tiene soporte específico para X11. Simplemente estamos subiéndonos a caballito de SSH. Dicho esto, la configuración actual es “suficientemente buena” para la mayoría de los casos.

Así que espero que este artículo haya desmitificado como interactuán el cliente y el servidor PulseAudio y las distintos archivos/variables de configuración que entran en juego. Si tenés cualquier pregunta, por favor preguntá en los comentarios y me esforzaré en actualizar el artículo.

El sonido en Linux es confuso: Clarificando Parte 1: ALSA

Lo que sigue es una traducción “quick and dirty” del primero de dos excelentes artículos escritos por Colin Guthrie. Todo comenzó por mi intento de desentrañar la manera en que Linux maneja el audio por estos días. Luego dí con Colin Guthrie el encargado de la parte de sonido en Mandriva, el cual tuvo la amabilidad de responder varias de mis preguntas, y al parecer todo esto fue un disparador para que él escribiera estos dos posts altamente recomendables, aquí va el primero (el original en inglés del primer artículo se puede leer haciendo clic aquí):

Ya que oigo la frase: “El sonido en Linux es confuso”. Si bien no discrepo totamente con ese comentario, como con todo en Linux el sistema de sonido es bastante lógico y si seguís bien los pasos podés desmitificar  cosas bastante rápido. Así que este artículo explica como funcionan las cosas en Mandriva y debería asegurar a los usuarios para que estén más cómodos con “como funcionan las cosas”.

Primero de todo deberíamos probablemente explicar un poquito como funciona esto. ALSA es la Arquitectura Avanzada de Sonido de Linux. Es un reemplazo para OSS (Open Sound System) que tenía varios problemas en Linux y que últimamente ha sido suplantado por ALSA como el único sistema de sonido en el Kernel. A pesar de una distensión de los términos de la licencia y últimos desarrollos de OSSv4, es improbable que OSS reemplace a ALSA en la línea principal del kernel.

ALSA tiene un componente en espacio de usuario, libasound, que actúa como la primera interfaz para la capa en nivel driver. La mayoría de las quejas acerca de la complejidad del API ALSA se relacionan en realidad a este componente en espacio de usuario, no con la capa en el nivel del kernel, que como podrías esperar, está controlada mucho más rigurosamente. No sufre de la misma necesidad de permanecer retrocompatible con las distintas aplicaciones en espacio de usuario (los drivers del kernel de ALSA solamente necesitan funcionar on libasound que puede obviamente desarrollarse en paralelo) llevando así a un diseño más limpio que la capa de espacio de usuario mismo que tiene que permanecer retrocompatible.

Además de servir de interfaz con la capa en el nivel del kernel e interactuar con el hardware físicamente instalado, ALSA también tiene una arquitectura de plugins. Este sistema de plugins permite a los dispositivos ser simulados/emulados, de distintas interesantes maneras. Permite, por ejemplo crear un dispositivo nulo que envia todo el audio a  /dev/null, permite a los auriculares bluetooth ser usados (notar que esto se considera una manera obsoleta en estos días), y permite que todo el audio sea encaminado a través de PulseAudio el cual discutiré más tarde en un subsiguiente artículo.

Así que, hablemos acerca de los archivos de configuración de ALSA. Ahora la mayoría de los archivos de configuración de ALSA viven en:

/usr/share/alsa/

Se puede afirmar que no son realmente archivos de “configuración” en el sentido clásico, i. e. no significa que tengas que cambiarlos como un usuario de acuerdo a tus propias preferencias y caprichos — son realmente más bien como archivos de código fuente y definen la estructura de los distintos plugins de ALSA y  configuraciones multicanal. A menos que estés desarrollando/hackeando en ALSA, probablemente no deberías modificar la gran mayoría de los archivos en esta carpeta.

El principal archivo

/usr/share/alsa/alsa.conf

define una lista de archivos adicionales para procesar y el orden en el cual procesarlos. Para incorporar PulseAudio de una elegante y configurable manera, hacemos algunos cambios a la lista de archivos adicionales:

--- alsa-lib-1.0.15rc3.lennart/src/conf/alsa.conf	2007-10-17 18:28:03.000000000 -0400
+++ alsa-lib-1.0.15rc3/src/conf/alsa.conf	2007-10-17 18:33:10.000000000 -0400
@@ -8,6 +8,8 @@
 	{
 		func load
 		files [
+			"/usr/share/alsa/pcm/pulseaudio.conf"
+			"/etc/alsa/pulse-default.conf"
 			"/etc/asound.conf"
 			"~/.asoundrc"
 		]

El primer archivo nos permite definir un “dispositivo” para ALSA llamado “pulse”. Esto está siempre presente aun si el usuario decide finalmente no usar PulseAudio de manera predeterminada en su máquina. Esto les permitiría e.g. definir un servidor PulseAudio remoto (vía variables de entorno o configuracion de client.conf – ver el próximo artículo en esta serie, enlazado debajo) y les dice a las aplicaciones de ALSA que usen este “dispositivo” específicamente. Se puede afirmar que este es un caso extremo, pero no hay razón para no sostener esto sin embargo :)

El segundo archivo nos permite activar PulseAudio de manera predeterminada. Esto es bastante importante ya que ofrece a los usuarios una manera sencilla de habilitar/deshabilitar PulseAudio es altamente deseable. La implementación de PulseAudio no está completamente libre de problemas y darles a los usuarios la capacidad de deshabilitar rápida y fácilmente es esencial. Firmemente creo que todos al final usarán PulseAudio, pero llevará tiempo para cada programa soportarlo completamente (quitando el uso de API ALSA “segura”) y para que los problemas de drivers sean resueltos apropiadamente.

En este segundo archivo, o bien comentamos el archivo completamente para deshabilitar PulseAudio de manera predeterminada, o lo dejamos decomentado para habilitar PulseAudio. Esto es manejado por draksound para que los usuarios solamente vean una interfaz gráfica sencilla que es una simple pero efectiva solución. Dicho esto, probablemente cambiaré este archivo para Mandriva 2010.0, cambiando a un sistema manejado por “Alternatives” ¡aunque esto realmente no importa en el esquema de cosas!

Entonces cuando la aplicación ALSA arranque, procesa todos estos archivos y finalmente resuelve como encaminar tu audio. 99% de las veces, el dispositivo “predeterminado” es usado (y uso “dispositivo” en el sentido menos estricto posible). Para una instalación de Mandriva estándar, el dispositivo de manera predeterminada es realmente PulseAudio (via el plugin PulseAudio para ALSA).

Entonces ¿qué pasa después? En el siguiente artículo, voy a hablar acerca de como una aplicación ALSA (o cualquier cliente PulseAudio) funciona cuando se conecta a PulseAudio.

Agregado al wiki de Mandriva

Agregué lo siguiente al Wiki de Mandriva, tal vez sea un uso avanzado, pero creo que estos comandos realizan tareas muy útiles:

urpmscan y urpmseek: Emulando apt-cache search

No se trata de comandos oficiales, más bien se trata de dos artificios para para realizar búsquedas de paquetes con un comportamiento similar al de apt-cache search de las distribuciones estilo Debian.

urpmscan devuelve una lista sencilla de acuerdo a una cadena de texto contenida en la descripción del paquete.

Para valerse de urpmscan, crear un archivo llamado urpmscan con el siguiente contenido y moverlo a /usr/bin

#! /bin/bash
urpmf -i  --uniq --description "$1"| grep  '^[[:alnum:]].*:$'|sed s/\:// |sort

Luego asignarle permisos de ejecución con:

chmod 755 /usr/bin/urpmscan

Y luego para buscar paquetes relacionados con streaming:

urpmscan streaming

urpmseek busca en el resumen de cada paquete y devuelve el listado con el nombre de los paquetes y su correspondiente sumario.

Si ademas, lo que se desea es en cambio buscar en el resumen del paquete se puede crear un alias llamado urpmseek:

echo alias urpmseek\=\"urpmf -i --summary\" >> /etc/bashrc

Para ponerlo en práctica inmediatamente se debe hacer:

bash

Y luego siguiendo el ejemplo anterior con urpmscan:

urpmseek streaming

Mandriva vuelve a parecerse a Mandrake

Después de las desafortunadas versiones 2005 y 2006 de Mandriva, esta distribución ha tratado de recuperar la posición pérdida. Sin embargo,  salió Mandriva 2009.0 y no me dejó la mejor impresión.

Tal es así que en mi escritorio personal me mudé durante algunos meses a Ubuntu.

Sin embargo, en el escritorio del trabajo seguía usando Mandriva, aunque con bastantes contratiempos debidos al el pobre desempeño en la gestión de paquetes que padecía luego de instalar la 2009.0. Decidí actualizar hace unas semanas directamente por urpmi de 2009 a 2009 Spring, más que nada para probar y luego sí, hacer una instalación limpia. Y el resultado fue ciertamente sorprendente, la actualización pasó prácticamente desapercibida.

Es importante remarcar que la actualización se hizo mientras estaba trabajando, el resultado fue gratamente sorprendente.

Entonces decidí volver en mi escritorio personal a Mandriva. Estaba vez instalando a partir de la versión de One. El resultado fue similar aunque noté un único bug importante que arrastra de versiones anteriores, si se utiliza un directorio personal ya existente,  con muchos archivos con el UID 500, el primer inicio de sesión se demora muchísimo. Esto es porque el sistema busca reemplazar todas las apariciones en los archivos de configuración /home/guest para reemplazarlos por el /home/nombre_de_usuario.

En link citado aquí, hay un workaround, pero ciertamente debería buscarse una solución mucho más elegante y práctica, o al menos avisar al usuario del proceso que se está realizando.

Más allá de eso, debe decirse que Mandriva 2009 Spring parece ser una edición depurada con mucho más minuciosidad y prolijidad que las anteriores, especialmente de la fallida 2009.

Todas las distribuciones tienen fortalezas y debilidades. Si hay algo que me gusta de Mandriva para usarlo como escritorio es la cohesión del entorno y de las herramientas, lo cual hace que sea para mí la distro a elegir cuando la cantidad de bugs y/o desprolijidades no alcanza niveles que amenazan aquellas virtudes.

Una mención especial merece la versión de KDE 4 que parece resolver muchos de los inconvenientes de las ediciones pasadas.

Otra cosa que me gustó fue nuevo diseño artístico de la edición Free, mucho más profesional comparándolas con versiones anteriores.

Hay una detalle tal vez no muy conocido y que no está en los repositorios, me refiero al mandriva-seed.sh. Se trata de un script que se vale de makeself y dd principalmente para volcar un archivo iso a un pendrive

La 2009.1 Spring es una versión ciertamente recomendable para usarla como sistema de escritorio. Es la mejor versión de Mandriva, desde que así se llama la distribución.

Mandriva 2009 Spring

Mandriva 2009 Spring

Mandriva 2009 y además LPI

Bajé e instalé Mandriva 2009. Probablemente sea la primera distro con una versión de KDE 4.x utilizable. Cosas que me gustaron: la nueva cara del Mandriva Control Center, esa idea tan Mandrake de una distro fácil, amigable y potente a la vez. Otro acierto es el menú de KDE 4 a la antigua.

Centro de Control de Mandriva

Centro de Control de Mandriva

Lamentablemente tiene las históricas desprolijidades de Mandrake/Mandriva, por ejemplo, algunos mirrors que no funcionan, las vueltas que hay que hacer para reproducir una película de un DVD usando compiz. No es que sea difícil, pero es molesto. Algo que no se entiende es: ¿Por qué no se activan por defecto las configuraciones que funcionan seguro con compiz? ¿Por qué esperar a que el usuario tenga que hacerlo? Otra cosa increíble es que se incluyan herramientas propias de la distribución que no funcionan correctamente. ¿No era mejor excluirla o ponerla en los repositorios de testing? Otra cosa irritante es padecer las falencias de una placa wireless Broadcom Corporation BCM4311 802.11b/g WLAN (rev 01). Y la herramienta de Mandriva para configuración de redes que hace fácil lo difícil, pero también complica lo sencillo, ¿por qué a veces es más complicado conectarse a una red inalámbrica abierta?

Y lo peor, puede ser que la distribución no sea la causante, pero ¿porqué luego de instalar Mandriva la unidad de DVD olvide su configuración de la región?

Bueno, aun así el saldo es positivo, por ahora me gusta esta nueva versión. La recomiendo. Los que no saben nada de Linux que quieran usarla como con cualquier otra distribución, les sugiero que busquen algo que tenga el tiempo y la paciencia para ayudarlos. De hecho lo mismo pasa con Windows: los usuarios no técnicos casi siempre tienen alguien cerca que los asiste.

Invito a votar por la solución de los bugs de Mandriva tales como el 44186.

Ah, además ya tengo la primer certificación LPI, en otro orden de cosas…