Arquitectura
Gestión del ciclo de vida para máxima eficiencia y mínima latencia
En una arquitectura de grafos, cada nodo debe encapsular un kernel DSP con estado interno explícito y contratos bien definidos para las fases de preparación (prepare), procesamiento (process) y compromiso (commit).
Durante la fase prepare, deben validarse los formatos (canales, stride y alineación) y solicitarse memoria a pools pre-dimensionados para evitar reserva dinámica en el hilo de audio. En process, deben aplicarse transformaciones optimizadas con alineación de 16 o 32 bytes, prefetch conservador y loop unrolling únicamente cuando aporte ganancias medibles.
La fase commit debe publicar contadores de lectura/escritura, y actualizar máquinas de estado finitas (por ejemplo, colas de envelopes, look-ahead de dinámica o resamplers fraccionarios), aplicando barreras de memoria mínimas para evitar tearing o inconsistencias.
Precisión
El pipeline numérico debe priorizar la estabilidad y la precisión. Los operadores con acumulación —como filtros IIR, sumadores de buses o detectores RMS— deben realizar la aritmética en Float64 mientras que la ruta de paso de señal debe mantenerse en Float32 para maximizar throughput y reducir la presión de memoria.
Las conversiones entre dB y valores lineales, los panning laws y los escalados deben aplicar epsilon floors para evitar denormals y preservar gradientes suaves en el rango subumbral. Los generadores de rampas deben ofrecer automatización sample-accurate.
La selección de la tasa debe validarse durante la fase prepare y permanecer fija durante el bloque, evitando cambios de política en el procesamiento.
Procesamiento
Las operaciones de alto costo —como convolución o análisis— deben implementarse mediante FFT particionada y tamaños de ventana ajustados al blockSize del contexto.
En convoluciones de cola larga (IR/HRTF), se deben combinar particiones pequeñas para las primeras reflexiones (baja latencia) y particiones grandes para la cola (alta eficiencia), utilizando crossfades sample-accurate al cambiar impulsos.
El procesamiento por bloques debe garantizar ejecución estable.
Cada kernel debe operar sobre buffers temporales en memoria contigua, permitiendo que el grafo se expanda a cientos de nodos sin aumentar la latencia.
Última actualización