"Después del juego es antes del juego"
Sepp Herberger

martes, 7 de marzo de 2017

2x1: multiseat en las aulas (Parte III)

Bueno, tenía que llegar tarde o temprano al tema del sonido en multiseat. Tras montar el multiseat aquí y aquí hace varios días me pidieron hacer funcionar el sonido de forma autónoma en cada seat.

1. Configuracion del seat.

En la entrada anterior le dediqué un apartado al tema y concluí que si usamos homes montados sobre NFS había que poner 2 tarjetas de sonido físicas, ya que pulseaudio no funcionaba bien por separado en cada seat compartiendo una única tarjeta. Así que he pinchado una tarjeta PCI de sonido normalita sacada de algún desguace de PC de los 90. El lspci me muestra esa tarjeta de audio adicional:
# lspci | grep -i audio
00:1b.0 Audio device: Intel Corporation 82801JI (ICH10 Family) HD Audio Controller
06:00.0 Multimedia audio controller: Ensoniq ES1370 [AudioPCI]
Como siempre, por defecto ambas tarjetas están vinculadas al seat0, veámoslo:
# loginctl seat-status seat0 | grep sound

          ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0
          │ sound:card0 "Intel"
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input10
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input11
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input12
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input13
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input14
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input15
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input16
          │ └─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input17
          ├─/sys/devices/pci0000:00/0000:00:1e.0/0000:06:00.0/sound/card2
          │ sound:card2 "AudioPCI"
          ................
          ................
Ahora vinculamos la tarjeta nueva, como ya vimos en las anteriores entradas, al seat-1:
# loginctl attach seat-1 "/sys/devices/pci0000:00/0000:00:1e.0/0000:06:00.0/sound/card2"
¿Estará ya en seat-1?. Como dicen en las Vegas Altas, vela ahíla:
# loginctl seat-status seat-1
seat-1
        Sessions: *c2
         Devices:
                  ├─/sys/devices/pci0000:00/0000:00:06.0/0000:02:00.0/drm/card0
                  │ drm:card0
                  ├─/sys/devices/pci0000:00/0000:00:06.0/0000:02:00.0/drm/renderD128
                  │ drm:renderD128
                  ├─/sys/devices/pci0000:00/0000:00:06.0/0000:02:00.0/graphics/fb0
                  │ [MASTER] graphics:fb0 "nouveaufb"
                  ├─/sys/devices/pci0000:00/0000:00:1d.7/usb2/2-2
                  │ usb:2-2
                  │ ├─/sys/devices/pci0000:00/0000:00:1d.7/usb2/2-2/2-2.1/2-2.1:1.0/0003:046D:C050.0001/input/input5
                  │ │ input:input5 "Logitech USB-PS/2 Optical Mouse"
                  │ └─/sys/devices/pci0000:00/0000:00:1d.7/usb2/2-2/2-2.2/2-2.2:1.0/0003:046D:C312.0002/input/input6
                  │   input:input6 "LITEON Technology USB Multimedia Keyboard"
                  └─/sys/devices/pci0000:00/0000:00:1e.0/0000:06:00.0/sound/card2
                    sound:card2 "AudioPCI"
Al reiniciar e iniciar sesión, podemos ver con un "ps aux" que pulseaudio se ejecuta en 3 instancias: una para lightdm y otra para cada una de las 2 sesiones en sendos seat.

El chasco viene cuando descubrimos que ambos seat reproducen el sonido por la tarjeta de audio Intel, ignorando la Ensoniq... ¿qué pasa aquí?. Si miramos la configuración de audio con pavucontrol en cualquiera de los seat vemos:
Horror de horrores: ambos seat ven las dos tarjetas de audio. Esto no es lo que me habían contado. Cada pulseaudio debería ver solo la tarjeta asociada a su seat, como sucede con los teclados, ratones y VGA. Esto tiene toda la pinta de ser un bug de pulseaudio que no maneja bien el tag ID_SEAT definido en su rules.d, pero no sé como arreglarlo en ese nivel.

2. El truco para activar una u otra tarjeta de sonido según el seat.

Lo que si me doy cuenta en la imagen anterior es que yo puedo, en cada combo, seleccionar el perfil "Desactivado" en una u otra tarjeta y conseguir que el sonido salga por la Intel o la Ensoniq, ignorando la otra. Eso es una rendija por la que colarse: si puedo hacerlo a mano...¿podria hacerlo al iniciar sesión en función del seat?. Dicho de otra manera...¿puedo controlar pulseaudio con comandos?. Pues si, encuentro en esta entrada que existe el comando "pacmd" que permite controlar todos y cada uno de los parámetros de una instancia de pulseaudio, incluyendo hacer copias de seguridad y restaurarlas. Con:
 ~$ pacmd help
Available commands:
    help                      Show this help
    list-modules              List loaded modules
    list-cards                List cards
    list-sinks                List loaded sinks
    list-sources              List loaded sources
    list-clients              List loaded clients
    list-sink-inputs          List sink inputs
    list-source-outputs       List source outputs
    ......
    play-file                 Play a sound file (args: filename, sink|index)
    dump                      Dump daemon configuration
    dump-volumes              Debug: Show the state of all volumes
    shared                    Debug: Show shared properties
    exit                      Terminate the daemon
Vemos todos los posibles comandos para obtener o fijar los parámetros de configuración. Con "pacmd dump > config.txt" haríamos una copia de seguridad, que podríamos restaurar con "pacmd < config.txt". Profundicemos: realmente la configuración de pulseaudio se guarda en:
 ~$ ls -1 ~/.config/pulse
cookie
e8418e23c6b647548fea260c81d4742b-card-database.tdb
e8418e23c6b647548fea260c81d4742b-default-sink
e8418e23c6b647548fea260c81d4742b-default-source
e8418e23c6b647548fea260c81d4742b-device-volumes.tdb
e8418e23c6b647548fea260c81d4742b-stream-volumes.tdb
Siendo los .tdb un tipo de BBDD bastante simple basado en pares "clave/datos binarios" usados principalmente en Samba. Son bastante crípticos incluso con la herramienta tdbtool, ya que guardan la información en formato binario, así que los ignoraremos y usaremos pacmd que es menos huraño.

Una curiosidad es el prefijo "e8418e23c6b647548fea260c81d4742b" de cada fichero. Es un UUID que sospecho que va asociado a la máquina, aunque no he podido averiguar de donde sale, y que permite tener configuraciones separadas de pulseaudio en función de la máquina en la que inicia sesión el usario, lo cual es muy útil cuando nuestros usuarios tienen un home centralizado en un servidor NFS.

Bueno, vamos al lío: tenemos que activar una u otra tarjeta al iniciar sesión en función del seat. Esto lo enfocaré como un parche temporal ya que según dice la parte contratante de la primera parte cada instancia de pulseaudio debería asociarse a la tarjeta de sonido vinculada seat correspondiente y santaspascuas. Hasta que esto sea cierto usaremos estos scripts para hacer funcionar el sistema:
# cat /usr/bin/multiseat-sound
#!/bin/bash
if [ "$XDG_SEAT" = "seat0" ]
then
   pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo
   pacmd set-card-profile 1 off
else
   pacmd set-card-profile 0 off
   pacmd set-card-profile 1 output:analog-stereo+input:analog-stereo
fi
Sencillo: si estamos en seat0 la tarjeta 0 se activa y la 1 se desactiva. Si es seat-1 se realiza la acción opuesta. Los valores output:analog-stereo+input:analog-stereo y off los he obtenido cambiando en pavucontrol a golpe de ratón y luego husmeando con "pacmd dump". Como queremos que esto se ejecute en cada inicio de sesión, metemos un .desktop en xdg/autostart:
# cat /etc/xdg/autostart/multiseat-sound.desktop
[Desktop Entry]
Type=Application
Name=Multiseat-Sound
Comment=Configura sonido por multiseat
Exec=/usr/bin/multiseat-sound
Terminal=false


3. Limpiando la casa.

Por último, si queremos quedar todo en recogido y en orden al salir de sesión debemos configurar un script de salida en lightdm:
 # cat /etc/lightdm/lightdm.conf.d/14-logout.conf
[SeatDefaults]
session-cleanup-script=/usr/bin/multiseat-sound-off
Siendo
# cat /usr/bin/multiseat-sound-off
#!/bin/bash
pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo
pacmd set-card-profile 1 output:analog-stereo+input:analog-stereo
Y con esto ya podemos tocar duetos con nuestros multiseat. Hasta podemos lanzar un duelo de guitarras haciendo salir por una a Joe Satriani y por otra a Yngwie Malmsteen y así alcanzamos el Nirvana en dobleplusestéreo.



No hay comentarios:

Publicar un comentario