[ubuntu-ar] ...consulta sobre video HDMI y sonido...una potencial solucion

Victor Castro Perez victorcp2004 at gmail.com
Thu May 28 17:03:36 UTC 2015


     ...en primera instancia gracias a todos los que contestaron que me 
ayudaron a masticar un poco mas el problema. Efectivamente no es un 
trabajito simple y las reglas UDEV son la clave del asunto. Estoy 
trabajando una solución adaptada de aqui 
<http://www.ms.unimelb.edu.au/%7Etrice/linux/tricks/hdmi/>. Es una 
solucion para archlinux, que no es dificil de readaptar para 
ubuntu/debian con algo de picardía. Para los que van duros de ingles 
aquí va la descripción traducida y explicada:

En primera instancia hay que identificar quien es quien en cuanto al 
sonido. Para variar hay un comando que nos tira la info necesaria:
--------------------------------------------------------------------------------------------------------
root en Portatil2:~# aplay -l
**** Lista de PLAYBACK dispositivos hardware ****
tarjeta 0: PCH [HDA Intel PCH], dispositivo 0: CS4213 Analog [CS4213 Analog]
   Subdispositivos: 1/1
   Subdispositivo #0: subdevice #0
tarjeta 0: PCH [HDA Intel PCH], dispositivo 3: HDMI 0 [HDMI 0]
   Subdispositivos: 1/1
   Subdispositivo #0: subdevice #0
root en Portatil2:~#
--------------------------------------------------------------------------------------------------------
No es necesario usar sudo o loguearse como root, "aplay -l" da la info 
aun cuando seas un humilde usuario. En este ejemplo vemos que el 
dispositivo 0 es la salida analogica y el 3 la HDMI. Esta es la 
configuración clásica del sonido en Linux.
El plan consiste en detectar los cambios en el conector HDMI y lograr 
que la fuente de sonido maestra del equipo pase de la 0 a la 3 (y 
viceversa) cuando sea necesario.
Para eso usamos las reglas UDEV y mosconeamos lo que pasa en el conector 
HDMI propiamente dicho. El estado lo reporta con el siguiente comando:
--------------------------------------------------------------------------------------------------------
root en Portatil2:~# cat /sys/class/drm/card0-HDMI-A-1/status
disconnected
root en Portatil2:~#
--------------------------------------------------------------------------------------------------------
El comando solo reporta como root o con el uso de sudo, esto causa 
alguna complicación. Un plan simple, cuando conectas o desconectas el 
HDMI se ejecuta el código de arriba como root y de algún modo forzas a 
que la placa de sonido por defecto pase del analogico al HDMI segun sea 
necesario. La detección de las conexiones esta a cargo del UDEV y sus 
reglas. En este caso particular basta con ir hasta /etc/udev/rules.d y 
crear un archivo que llamaremos "100-hdmi.rules" (sin las comillas!). El 
contenido del archivo es el siguiente:
-------------------------------------------------------------------------------------------------------
#Regla de autodeteccion de HDMI
SUBSYSTEM=="drm", ACTION=="change", RUN+="/bin/bash /etc/alsa/hdmi-switch"

------------------------------------------------------------------------------------------------------
Y el contenido del directorio /etc/udev/rules.d queda asi:
------------------------------------------------------------------------------------------------------
root en Portatil2:/etc/udev/rules.d# ls -l
total 16
-rw-r--r-- 1 root root   75 may 27 14:17 100-hdmi.rules
-rw-r--r-- 1 root root   97 oct  8  2014 60-ssd-scheduler.rules
-rw-r--r-- 1 root root  629 ago  4  2014 70-persistent-net.rules
-rw-r--r-- 1 root root 1157 abr 14  2014 README
root en Portatil2:/etc/udev/rules.d#
------------------------------------------------------------------------------------------------------

Como siempre, ojo con los permisos.
En el original el archivo se llama "hdmi.rules" a secas, esto hace que 
se verifiquen DESPUES de cualquier otra regla preexistente. Con el 
nombre que yo le puse la regla se verifica ANTES que las preexistentes 
con numero menor. Como UDEV parsea en secuencia las reglas y se supone 
que uno usa el HDMI bastante seguido (mas seguido que el scheduler de 
los ssd y el cambio dinámico de placa de red en mi caso) hay cierta 
ventaja en tiempos de reaccion. Como siempre conviene probar el rendimiento.
Por cierto, que es lo que dice esta regla de UDEV?. Traducido a humano 
seria así: Cuando en el subsistema "drm" ocurre un cambio, ejecute un 
shell y haga correr un script llamado hdmi-switch que se encuentra en el 
directorio /etc/alsa.
Vayamos a lo primero, creamos un directorio llamado alsa dentro del etc. 
Usen la herramienta que prefieran, como antiguo usuario del norton 
commander mi favorito es el midnight commander., pero lo importante es 
que el directorio tenga los atributos correctos. Quedaria algo asi:

--------------------------------------------------------------------------------------------------------
root en Portatil2:/etc# ls -l
total 1288
drwxr-xr-x  3 root     root       4096 jul 22  2014 acpi
-rw-r--r--  1 root     root       2981 jul 22  2014 adduser.conf
drwxr-xr-x  2 root     root       4096 nov  4  2014 akonadi
drwxr-xr-x  2 root     root       4096 may 27 14:42 alsa
drwxr-xr-x  2 root     root      12288 may 27 13:07 alternatives
-rw-r--r--  1 root     root        401 feb 19  2014 anacrontab
drwxr-xr-x  3 root     root       4096 ago  4  2014 apache2
...
drwxr-xr-x  4 root     root       4096 jul 22  2014 xdg
drwxr-xr-x  2 root     root       4096 ago  4  2014 xml
drwxr-xr-x  2 root     root       4096 ene 17 07:28 xul-ext
-rw-r--r--  1 root     root        349 jun 26  2012 zsh_command_not_found
root en Portatil2:/etc#
--------------------------------------------------------------------------------------------------------

Observen que alsa tiene permisos consistentes con el resto de los 
directorios de /etc/. Atencion con este detalle porque muchas veces es 
el origen de bonitos dolores de cabeza.
Ya tenemos el directorio, ahora vamos a meterle cosas adentro. En primer 
lugar necesitamos al script que hace el trabajo sucio. Abrimos el editor 
que mas les guste y haciendo uso de los permisos de root mandamos lo 
siguiente:

---------------------------------------------------------------------------------------------------------
#! /bin/bash
set -x

udevadm settle --quiet --timeout=16
hdmi_status=$(cat /sys/class/drm/card0-HDMI-A-1/status)
alsa_dir=/etc/alsa
asound_file=asound.hdmi-$hdmi_status

     if [[ -n $hdmi_status ]] && [[ -f "$alsa_dir/$asound_file" ]]; then
         ln -sf "$alsa_dir/$asound_file" /etc/asound.conf
         /sbin/alsa force-reload
     fi

---------------------------------------------------------------------------------------------------------

La version de este script puede variar ligeramente segun se trate de que 
"sabor" de linux estemos usando. Atencion con la locacion del ejecutable 
alsa. En archlinux esta en : "/etc/rc.d/alsa" y es algún tipo de 
servicio manejado a la antigua usanza (por eso el comando es 
force-restart). En los ubuntu mas modernos esto no es así y debemos 
tratar directamente con el ejecutable alsa que se encuentra en 
/sbin/alsa y obedece a comandos ligeramente diferentes.
En humano, el script hace lo siguiente. en primera instancia hace 
algunos ajustes para la ejecucion del script (set -x), el comportamiento 
de udev (udevadm settle --quiet --timeout=16) y pasa directo a los 
bifes. Verifica la situacion del conector HDMI y carga la variable de 
estado en hdmi-status. Para lograrlo recurre al pequeño codigo que 
detallamos mas arriba. Como ese codigo requiere permisos de root este 
script va a tener que tener los permisos adecuados o simplemente no 
funcionara.
Esta variable puede tomar dos estados, connected o disconnected segun lo 
que pase con el enlace HDMI. Atención con este detalle. Yo puedo tener 
el cable enchufado y la tele apagada o no seleccionada la entrada, en 
este caso es disconnected. Solo cuando todo esta activado pasa a connected.
Acto siguiente carga en una variable el valor del directorio alsa 
(siempre es el mismo: /etc/alsa) y el valor del archivo asound. Los que 
se han roto la cabeza arreglando el sonido de linux tienen un 
dulce/amargo (tachese lo que no corresponda) recuerdo de este archivo. 
En el motor de sonido alsa asound es el archivo maestro de configuración 
del sistema de sonido. Si reside en /etc/ modifica a todo el sistema y 
se llama asound.conf, cuando reside en el directorio del usuario solo 
afecta al mismo y se lama .asoundrc. Ambos hacen prácticamente lo mismo 
y en particular permiten establecer la salida de sonido maestra del 
sistema (esto es lo que estamos buscando toquetear!).
Si observamos con detalle el script vemos que la variable asound_file 
puede tomar dos valores según el estado del HDMI. Una tablita de valores 
nos muestra lo que pasa:


*HDMI * 	*$hdmi_status * 	*asound.hdmi-$hdmi_status*
conectado 	connected 	asound.hdmi-connected
desconectado 	disconnected 	asound.hdmi-disconnected


  Acto seguido evalúa primero que $hdmi_status tenga un valor coherente 
y si eso es cierto que $alsa_dir/$asound_file 
(/etc/alsa/asound.hdmi-connected o /etc/alsa/asound.hdmi-disconnected 
según corresponda) exista y sea un archivo regular. Interesante forma de 
saber que el proceso de deteccion tuvo éxito.
Si todo esta bien hacemos un enlace simbólico entre /etc/asound.conf y 
alguno de los dos archivos de configuración que pueden existir. Esta es 
la linea que hace el cambio en la salida de sonido. Cuando se llevo a 
cabo, se procede a reiniciar el motor alsa con los nuevos archivos.
Solo nos quedan dos cosas mas para terminar el combo. Los archivos que 
efectivamente obligan a alsa a cambiar.

El primero "asound.hdmi-connected" :


-------------------------------------------------------------------------------------

pcm.!default {
     type hw
     card 0
     device 3
}
ctl.!default {
     type hw
     card 0
     device 3
}

-------------------------------------------------------------------------------------

El segundo "asound.hdmi-disconnected" :

-------------------------------------------------------------------------------------

pcm.!default {
     type hw
     card 0
     device 0
}
ctl.!default {
      type hw
     card 0
     device 0
}
--------------------------------------------------------------------------------------

Ambos archivos, junto a hdmi-switch deben residir en el directorio 
"/etc/alsa". Cuando esta todo en orden se ve así:

--------------------------------------------------------------------------------------

root en Portatil2:/etc/alsa# ls -l
total 12
-rw-r--r-- 1 root root 113 may 27 14:14 asound.hdmi-connected
-rw-r--r-- 1 root root 113 may 27 14:14 asound.hdmi-disconnected
-rwsr-sr-x 1 root root 323 may 27 14:42 hdmi-switch
root en Portatil2:/etc/alsa#

--------------------------------------------------------------------------------------

Presten atención a los permisos de hdmi-switch, cuando ejecuta lo hace 
con permisos de root. Debe haber una forma mas segura de hacer esto pero 
no me puse a buscarla.
Una vez que tenemos montado todo el circo, solo basta con hacer:

---------------------------------------------------------------------------------------

sudo udevadm control --reload-rules

---------------------------------------------------------------------------------------

Esto pone en vigencia las nuevas reglas y activa todo el mecanismo. Los 
mas paranoicos pueden reiniciar pero no es realmente necesario.

_*TO-DO-LIST!!!!!!!!!!!!!!!!!*_

Resulta que no termina alli. A la monada que usa archlinux le basta con 
esto, pero los felices (WTF!) usuarios de KDE todavía tenemos que 
convencer al motor de sonido de la interfase grafica que haga el cambio 
pertinente. Que significa esto, que funciona correctamente y alsa se 
entera del cambio pero no entiendo por que no se comunica con pulse o 
quien sea que maneja el sonido cuando esta cargado KDE. Asi que sigo 
trabajando en el asunto. Deseenme suerte....


More information about the Ubuntu-ar mailing list