sergio/takana
> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…
⎇ 534014c3ec69daea789a1d0523e1d00a69c6ed65
recipes/pipewire-sound-initialized.patch
Ñawpa willay
ch'uya
pipewire al corpus: falta el parche, que quedó fuera del commit ajeno y dejó la receta rota
1⚠ ESTE PARCHE NO ERA EL BLOQUEO — leer antes de sacar conclusiones.
2
3Se escribió creyendo que `SOUND_INITIALIZED` era lo que impedía enumerar, y **no lo era**: con el
4parche aplicado, `wpctl status` seguía dando `Devices:` vacío. La causa real está más abajo en el mismo
5fichero y es ESTRUCTURAL, no una propiedad que falte (ver la nota al final).
6
7El parche se conserva porque la incompatibilidad que describe es REAL y volvería a morder en cuanto la
8enumeración funcione: sin él, SPA descarta toda tarjeta en un sistema sin udevd. Pero no es la
9solución del problema de audio.
10
11pipewire/SPA: no exigir `SOUND_INITIALIZED`, una propiedad que sólo pone udevd con sus reglas.
12
13EL SÍNTOMA, y por qué es caro de leer: con ALSA encendido en el kernel, la tarjeta detectada y
14`/dev/snd/controlC0` presente, `wpctl status` seguía dando
15
16 Audio
17 ├─ Devices: ← vacío
18 ├─ Sinks: * 33. Dummy Output
19
20o sea el MISMO cuadro que cuando no había kernel con sonido. Tres cosas distintas —no hay ALSA, no hay
21tarjeta, hay tarjeta y el stack no la ve— se ven idénticas en esa salida.
22
23LA CAUSA, en la fuente: `spa/plugins/alsa/alsa-udev.c:167`
24
25 if (udev_device_get_property_value(udev_device, "SOUND_INITIALIZED") == NULL)
26 return SPA_ID_INVALID; /* descarta la tarjeta */
27
28`SOUND_INITIALIZED` no es una propiedad del kernel: **la pone udevd al ejecutar sus reglas**
29(`78-sound-card.rules` de systemd/eudev marca la tarjeta cuando todos sus devices están listos). Esta
30distro usa **libudev-zero**, que lee /sys directo y NO EJECUTA REGLAS por diseño — su
31`udev_enumerate_scan_devices` recorre `/sys/dev/block` y `/sys/dev/char`, así que la tarjeta SÍ se
32enumera, pero llega sin esa propiedad. Resultado: SPA descarta todas las tarjetas, siempre.
33
34POR QUÉ SE PARCHEA PIPEWIRE Y NO libudev-zero: sintetizar `SOUND_INITIALIZED` en libudev-zero sería
35igual de correcto, pero `yupana radio libudev-zero` da **51 artefactos sellados cayendo a deuda** —
36está en el cierre de las cinco imágenes. El radio de pipewire son 2. Se paga el barato.
37
38POR QUÉ QUITAR EL GUARDA ES LEGÍTIMO Y NO UN ATAJO: ese `if` existe para no correr una carrera contra
39udevd —evitar tomar una tarjeta cuyos devices todavía no aparecieron—. **Con libudev-zero no hay
40udevd, así que no hay carrera que perder**: cuando `/sys/dev/char` lista el device, el device existe.
41Se elimina una comprobación cuya premisa no se cumple acá, no una que nos moleste.
42
43Lo que NO se toca: los otros tres guardas del mismo bloque (`ACP_IGNORE`, `SOUND_CLASS=modem`,
44`DEVPATH`). Los dos primeros son opt-out explícitos del administrador y el tercero es un dato real del
45kernel — ésos siguen valiendo.
46
47diff -Naur a/spa/plugins/alsa/alsa-udev.c b/spa/plugins/alsa/alsa-udev.c
48--- a/spa/plugins/alsa/alsa-udev.c
49+++ b/spa/plugins/alsa/alsa-udev.c
50@@ -164,8 +164,13 @@
51 if ((str = udev_device_get_property_value(udev_device, "SOUND_CLASS")) && spa_streq(str, "modem"))
52 return SPA_ID_INVALID;
53
54- if (udev_device_get_property_value(udev_device, "SOUND_INITIALIZED") == NULL)
55- return SPA_ID_INVALID;
56+ /* hammer: NO exigir SOUND_INITIALIZED. Esa propiedad la pone udevd al correr
57+ * 78-sound-card.rules, y esta distro usa libudev-zero, que lee /sys directo y no
58+ * ejecuta reglas. El guarda existe para no competir con udevd por una tarjeta a
59+ * medio inicializar; sin udevd no hay carrera: si /sys/dev/char lista el device,
60+ * el device esta. Ver recipes/incoming-gnome/pipewire-sound-initialized.patch.
61+ * Los otros guardas de este bloque (ACP_IGNORE, SOUND_CLASS=modem, DEVPATH) se
62+ * respetan tal cual: son opt-out del administrador o datos reales del kernel. */
63
64 if ((str = udev_device_get_property_value(udev_device, "DEVPATH")) == NULL)
65 return SPA_ID_INVALID;
66
67══ LO QUE SÍ BLOQUEA, medido después ═════════════════════════════════════════════════════════════
68`get_card_nr` sigue con dos comprobaciones más (alsa-udev.c:178-183):
69
70 if ((e = strrchr(str, '/')) == NULL) return SPA_ID_INVALID;
71 if (strlen(e) <= 5 || strncmp(e, "/card", 5) != 0) return SPA_ID_INVALID;
72
73o sea que **sólo acepta el device CARD** (`/sys/.../sound/card0`), no `controlC0` ni `pcmC0D0p`. Y
74`card0` es un device de CLASE: no tiene major:minor, no tiene nodo en /dev.
75
76`udev_enumerate_scan_devices` de libudev-zero recorre **exclusivamente** `/sys/dev/block` y
77`/sys/dev/char` (udev_enumerate.c:281) — o sea sólo devices CON nodo. El udev real enumera
78`/sys/class/*` entero, con nodo o sin él.
79
80⇒ **El device que SPA necesita nunca entra en la enumeración.** No hay guarda que sacar: falta la
81mitad del espacio de búsqueda.
82
83**YA RESUELTO (2026-07-30)**, y por el camino (a): `recipes/libudev-zero-scan-class.patch` enseña a
84libudev-zero a enumerar devices de CLASE para una lista acotada de subsistemas (hoy `sound`). Se
85descartó eudev porque sin udevd es PEOR —rompió el input en otro frente— y correr udevd contradice la
86arquitectura. El audio funciona: `48. HDA Intel [alsa]` con sink y source reales. Los detalles, y por
87qué la lista es acotada (recorrer `/sys/class` entero rompía el VÍDEO), están en ese parche.