audio: wireplumber (b3:39a9a06c) + lua (b3:e6c35f98) — y el Devices vacío es del KERNEL
Cierra el gestor de sesión de PipeWire, que es lo que separa «PipeWire acepta clientes» de «PipeWire tiene dispositivos». Su política está escrita en Lua, así que arrastró una receta de Lua que hubo que autorar entera. LO QUE LA RECETA DE LUA TIENE QUE INVENTAR: el Makefile de upstream sólo produce liblua.a y los binarios — **no hay regla de .so ni fichero pkg-config**, los agrega cada distro. Acá la compartida se enlaza a mano desde la .a con --whole-archive (una estática sólo aporta lo referenciado y hay que llevarse todo) y el .pc se escribe con los TRES nombres que se usan por ahí, porque wireplumber prueba lua-5.4, lua5.4 y lua54 en orden. `-fPIC` no es opcional: libwplua es un objeto compartido. Dos símbolos más en libelogind (tawasuyu 087230054 → re-pineado 749edfe41): sd_uid_get_seats y sd_uid_get_state, que module-logind.c de wireplumber usa para saber si el usuario está en un asiento antes de tomar los dispositivos. Van 28 símbolos sd-*. **EL `Devices:` VACÍO DE wpctl NO ES UN FALLO DE wireplumber: el kernel no tiene ALSA.** recipes/linux-metal.toml:111 lo apaga explícito (`-d SOUND -d SND`), así que no hay /dev/snd que enumerar. Y esto NO se dio por supuesto: se agregó una ich9-intel-hda emulada a QEMU (AUDIO=1, ahora el default de run-qemu-desktop.sh) justo porque un «Devices: vacío» se lee IGUAL si wireplumber funciona sobre una VM sin hardware que si no funciona. Con tarjeta y sin ALSA en el kernel, el resultado no cambia — la ambigüedad queda resuelta. Encender el sonido en la distro es una decisión con costo (re-sellar el kernel, rehacer la imagen metal) y queda a la vista en vez de escondida en un default. Bug propio destapado en el camino: el bloque de wireplumber quedó DUPLICADO en gnome-start y había DOS wireplumber peleándose el grafo. El síntoma no era un error sino una lista de clientes que se lee normal si no se cuenta: dos «WirePlumber» con pids distintos en wpctl status. Y una nota de ADR 0012 que costó un rato: la cascada de libelogind cortó a mitad y dejó el `output/` de mutter a medio hacer; el reintento moría con «error opening '...c.o.d': No such file or directory». Un `rm -rf output` en el configure NO alcanzó —el árbol tenía estado viejo más allá del build dir—; lo que lo arregló fue BORRAR work/sources/mutter-* para que el fetch lo re-extraiga limpio. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -292,15 +292,18 @@ esperar_nombre() {
|
||||
return 1
|
||||
}
|
||||
# ── AUDIO: PipeWire (decisión del usuario, 2026-07-29) ──────────────────────────────────────────
|
||||
# Van DOS procesos y el orden importa: `pipewire` es el servidor, y `pipewire-pulse` es el puente que
|
||||
# habla el protocolo de PulseAudio contra él. gnome-shell usa libpulse (gvc), así que lo que necesita
|
||||
# es el SEGUNDO; sin el primero, el segundo no tiene con quién hablar.
|
||||
# Van TRES procesos y el orden importa, porque cada uno es cliente del anterior:
|
||||
# 1. `pipewire` — el servidor. Crea $XDG_RUNTIME_DIR/pipewire-0.
|
||||
# 2. `pipewire-pulse` — el puente que habla el protocolo de PulseAudio contra él. Es lo que
|
||||
# gnome-shell necesita (gvc usa libpulse), y sin (1) no tiene con quién hablar.
|
||||
# 3. `wireplumber` — el gestor de sesión: enumera dispositivos y aplica la política. Sin él (1) y
|
||||
# (2) funcionan pero el único sink es `auto_null`, el nodo de descarte.
|
||||
# Los tres son servicios de USUARIO: sus sockets viven en $XDG_RUNTIME_DIR, creado más arriba.
|
||||
#
|
||||
# Los dos son servicios de USUARIO: su socket vive en $XDG_RUNTIME_DIR, que ya está creado más arriba.
|
||||
#
|
||||
# ⚠ Sin gestor de sesión (wireplumber todavía no está autorado): esto hace que el shell CONECTE y deje
|
||||
# de tirar `Gvc-WARNING: Failed to connect context: Connection refused`, pero NO enumera ni enruta
|
||||
# dispositivos. «El shell conecta» no es «hay sonido», y conviene no confundirlos.
|
||||
# ⚠ NO duplicar el bloque de wireplumber. Estuvo dos veces por un merge descuidado de este script y el
|
||||
# resultado fue DOS wireplumber vivos peleándose el grafo — visible en `wpctl status` como dos clientes
|
||||
# «WirePlumber» con pids distintos. El síntoma no es un error: es una lista de clientes que se lee
|
||||
# normal si no se cuenta.
|
||||
if [ -x /usr/bin/pipewire ]; then
|
||||
/usr/bin/pipewire >/tmp/pipewire.log 2>&1 &
|
||||
say "pipewire lanzado (pid $!)"
|
||||
@@ -315,6 +318,27 @@ if [ -x /usr/bin/pipewire ]; then
|
||||
else
|
||||
say "!! pipewire-pulse no creó pulse/native:"; dump /tmp/pipewire-pulse.log
|
||||
fi
|
||||
# wireplumber: el GESTOR DE SESIÓN. Va tercero porque necesita que el servidor ya esté; es el que
|
||||
# convierte «PipeWire acepta clientes» en «PipeWire tiene dispositivos»: enumera por udev/alsa y
|
||||
# aplica la política (qué es entrada, qué es salida, qué se enlaza con qué), y esa política está
|
||||
# escrita en Lua. Sin él el único sink es `auto_null`, el nodo de descarte.
|
||||
if [ -x /usr/bin/wireplumber ]; then
|
||||
/usr/bin/wireplumber >/tmp/wireplumber.log 2>&1 &
|
||||
WP_PID=$!
|
||||
say "wireplumber lanzado (pid $WP_PID)"
|
||||
sleep 2
|
||||
if alive $WP_PID; then
|
||||
say "wireplumber sigue vivo"
|
||||
# El dato que importa no es el pid sino QUÉ VE. `wpctl status` lista los nodos que la política
|
||||
# creó: si sale vacío, wireplumber corre pero no enumeró nada.
|
||||
wpctl status >/tmp/wpctl.log 2>&1 || true
|
||||
dump /tmp/wpctl.log
|
||||
else
|
||||
say "!! wireplumber MURIÓ:"; dump /tmp/wireplumber.log
|
||||
fi
|
||||
else
|
||||
say "!! sin wireplumber — PipeWire acepta clientes pero no habrá dispositivos"
|
||||
fi
|
||||
else
|
||||
say "!! pipewire no creó su socket:"; dump /tmp/pipewire.log
|
||||
fi
|
||||
|
||||
@@ -54,6 +54,8 @@ else
|
||||
# El SERVIDOR de audio (decisión del usuario: PipeWire, no PulseAudio). No es dep de build de
|
||||
# nadie: el shell habla libpulse y `pipewire-pulse` le contesta por el otro lado.
|
||||
recipes/incoming-gnome/pipewire.toml
|
||||
# Y su gestor de sesión, que es lo que hace que PipeWire tenga DISPOSITIVOS y no sólo un socket.
|
||||
recipes/incoming-gnome/wireplumber.toml
|
||||
)
|
||||
fi
|
||||
|
||||
|
||||
@@ -49,6 +49,17 @@ QEMU_ARGS=(
|
||||
-no-reboot
|
||||
)
|
||||
|
||||
# AUDIO=1 (default): darle a la VM una tarjeta de sonido EMULADA. No es para oír nada —el backend es
|
||||
# `none`, que descarta las muestras— sino para que HAYA UN DISPOSITIVO QUE ENUMERAR.
|
||||
#
|
||||
# Sin esto, `wpctl status` sale con «Devices:» vacío y un único sink `auto_null`, y ese resultado es
|
||||
# AMBIGUO: se lee igual si wireplumber funciona sobre una VM sin hardware que si wireplumber no
|
||||
# funciona. Con una ich9-intel-hda emulada, el árbol de /sys/class/sound existe y la respuesta
|
||||
# distingue las dos cosas. AUDIO=0 para volver al caso sin tarjeta.
|
||||
if [ "${AUDIO:-1}" = 1 ]; then
|
||||
QEMU_ARGS+=(-audiodev none,id=snd0 -device ich9-intel-hda -device hda-duplex,audiodev=snd0)
|
||||
fi
|
||||
|
||||
echo "==> QEMU (DISP=$DISP, serial=$SERIAL)"
|
||||
echo " imagen: $IMG"
|
||||
if [ -n "${TIMEOUT:-}" ]; then
|
||||
|
||||
Reference in New Issue
Block a user