Inicio / Motor de audio
Un motor que solo entrega.
El crate lucida-audio, en Rust, desacopla la lectura del archivo de la entrega al DAC en tres etapas. Aquí está cómo, y qué regla sigue cada una.
Del archivo al conversor, en tres etapas
Leer de disco o de la red, y esperar a otros procesos, puede provocar micro-pausas (underruns) que se oyen como chasquidos. Para aislar la reproducción de esas perturbaciones, el motor (ADR-0007) separa el trabajo en un canal de tres etapas.
- ETAPA 1 · PRIORIDAD ELEVADAHilo decodificador
Lee archivos locales o flujos HTTP y decodifica con Symphonia (FLAC, ALAC, WAV…) a enteros de 32 bits alineados al bit más significativo.
- ETAPA 2 · DESACOPLAMIENTOBúfer circular SPSC
Un anillo de capacidad fija (rtrb), sin bloqueos, que aísla el hilo de audio de la lectura de disco y de la red.
- ETAPA 3 · TIEMPO REALRender de salida
Con prioridad de tiempo real del sistema, toma las muestras del anillo y las empaqueta en bytes para el controlador del DAC.
Las cuatro reglas del hilo de render
El hilo de render es el único que toca los búferes del controlador de audio, así que su bucle sigue cuatro reglas.
- Memoria reservada al arrancar
- Ningún malloc ni redimensionado de vectores durante la reproducción: los búferes de trabajo se preasignan al abrir el dispositivo.
- Comunicación sin esperas
- Sin primitivas de sincronización bloqueantes: el hilo de control se comunica con variables atómicas y colas SPSC sin bloqueos.
- Solo cálculo
- Prohibido leer disco, hacer peticiones de red o tocar el sistema de archivos en el hilo de render. Toda la E/S vive en hilos preparatorios.
- El registro, fuera
- Prohibido emitir logs o formatear texto en la ruta crítica. Las métricas se acumulan en contadores atómicos.
Cada sistema, con su planificador
Corintia no trata el audio como un proceso más: pide prioridad de tiempo real al planificador propio de cada plataforma.
| SISTEMA | SALIDA | PRIORIDAD DEL HILO |
|---|---|---|
| Windows | WASAPI en modo exclusivo | MMCSS, clase «Pro Audio» |
| macOS | CoreAudio, con el dispositivo en exclusiva | IOProc del HAL con restricción de tiempo real |
| Linux (KDE y GNOME) | ALSA directo (hw:), sin dmix | SCHED_FIFO pedido a RealtimeKit (rtkit) |
Entre pistas
Para los álbumes en directo y la música clásica, la transición entre pistas se resuelve en el propio núcleo.
- Aviso anticipado
- Cuando faltan 30 segundos para el final de una pista, el motor pide a la app que prepare la siguiente.
- Mismo anillo
- Si la siguiente comparte frecuencia y canales, se escribe en el mismo anillo tras una marca de frontera: la transición es exacta a la muestra.
- Si cambia el formato
- Se drena el anillo, se entregan dos periodos de silencio controlado para evitar chasquidos y se reabre el dispositivo en el nuevo formato.
Un visualizador que no toca la señal
Muchos reproductores quitan el espectro por miedo a que el cálculo afecte al audio. Corintia (ADR-0010) hace una derivación en paralelo con pérdida: en el punto en que las muestras salen hacia el controlador se copian a un anillo secundario; si este se satura, las muestras de análisis se descartan sin retrasar nunca el hilo de audio.
Un hilo de baja prioridad aplica una ventana de Blackman y calcula una FFT agrupada en 64 bandas logarítmicas entre 20 Hz y 20 kHz. Sobre ellas, el motor compartido dibuja 37 escenas en siete familias, todas en la GPU. Las ves en la galería.
Cómo se verifica
La promesa de bit-perfect se comprueba en cada cambio del repositorio (LUCI-26):
- Salida de prueba
- Un backend en memoria (
MemoryOutput) captura cada byte que el render habría enviado al conversor. - Reloj virtual
- Permite simular reproducciones largas sin depender de hardware físico.
- Huella del PCM
- Cada trama de prueba se compara byte a byte con la huella MD5 del PCM de referencia: si un solo bit cambia, la integración continua falla.
Esto prueba el motor con salidas simuladas. La verificación con DACs físicos sigue su propio protocolo; ver el estado por sistema.