¿Existe una forma eficiente de sincronizar eventos de audio en tiempo real con LED usando una MCU?

Estoy trabajando en un proyecto en el que las luces LED se sincronizan con los eventos de audio. No me refiero a proyectos de LED reactivos que leen el ADC de la amplitud o el espectro de audio, sino a tener algunos datos digitales adicionales que se reproducen junto con el audio para indicar varios desencadenantes de eventos.

Inicialmente, el enfoque que estoy tomando es utilizar un archivo estéreo y tener un canal para audio y otro canal para datos. Se accede al archivo mediante un módulo de tarjeta SD y se procesa mediante un códec o un módulo reproductor de mp3. El canal con datos tiene pulsos de diferentes frecuencias de onda sinusoidal para indicar diferentes eventos y activar luces LED específicas.

Logré hacer esto usando un chip analizador de espectro, pero no es lo ideal ya que al usar el ADC hay fluctuaciones y los cambios en el control de volumen afectan la señal. Espero encontrar una solución de señal digital, ya que cuando se lee la tarjeta SD y se procesa el audio, los datos de un canal del archivo (wav o mp3) deben leerse en tiempo real en la MCU.

Idealmente, el MCU sería un ESP32. Experimenté con algunas bibliotecas que pueden leer archivos wav desde una tarjeta SD (como esp32_I2S_player) pero no pude recibir los datos para crear las 'condiciones if' necesarias. Otro intento fue ver si podía hacer esto con un códec VS1053, pero las bibliotecas para este chip tampoco brindan una función para leer datos de la tarjeta SD de un canal específico, y no pude encontrar mucho sobre esto en el ficha de datos.

Entonces mis preguntas son:

  1. ¿Existe una forma eficiente de sincronizar eventos de audio en tiempo real con LED usando una MCU? Sé cómo hacer esto a través del software general del sistema operativo, pero ahora la aplicación requiere una máquina básica.
  2. Si mi enfoque (archivo estéreo = datos + audio) tiene sentido, ¿cómo puedo implementarlo? ¿Existe un códec o MCU que facilite este enfoque? ¿Hay algún ejemplo de código que pueda ayudarme?

Me siento estancado en este tema, así que realmente aprecio sus respuestas. Gracias.

Encuentro que codificar ese tipo de cosas como audio en un archivo digital es algo incorrecto. Los archivos MP3 pueden contener etiquetas de letras con marcas de tiempo. Codifique sus comandos LED como texto en etiquetas de letras.
@JRE: Esa es realmente una buena respuesta, y debería escribirla como tal.
Estaba comprobando si es posible con las típicas bibliotecas ESP32 o Arduino. Parece que lo es. Lo escribiré y agregaré algunos detalles en un momento.
Depende de las especificaciones. Colocar un flujo de bits UART de baja velocidad en baudios en un canal de audio es bastante simple.
Una opción sería la reproducción simultánea de un flujo MIDI junto con su flujo de audio donde los datos de control de iluminación están codificados en la pista MIDI. En realidad, esto es bastante común con el control de iluminación de DJ/discoteca y puede encontrar mucha información de referencia una vez que sepa lo que está buscando.
En realidad, MIDI es la solución estándar en la industria.

Respuestas (4)

El uso de un DSP auxiliar para la descompresión puede dificultar esta tarea, a menos que se limite a archivos de tasa de bits constante; si necesita una alta precisión de tiempo de los eventos de luz, es posible que deba tener en cuenta el retraso en el procesamiento desde que ingresa los datos hasta que sale el sonido. , que sería diferente a diferentes velocidades de bits.

Posiblemente, podría trabajar con un decodificador distinto haciendo una temporización independiente, iniciando un contador de tiempo de MCU al comienzo de la salida de audio y activando eventos de luz en las marcas de tiempo apropiadas. En ese caso, es posible que desee codificar sus datos de luz en su propio archivo vinculado por un patrón de nomenclatura, o incrustarlos en datos entretejidos que aparecen un poco antes del audio comprimido al que corresponde y se retienen en un búfer de MCU hasta la marca de tiempo indicada .

Una posible simplificación drástica es almacenar archivos .wav PCM lineales en lugar de MP3 comprimidos. Dado que un CD de audio es solo alrededor de 3/4 de un gigabyte, incluso una tarjeta SD barata puede contener unas pocas horas de audio sin comprimir. Si no tiene compresión, es bastante simple para su MCU simplemente registrar los datos en un DAC, aunque preferiblemente use un DAC controlado por temporizador de hardware (y potencialmente DMA) o al menos una interrupción, no un bucle de retraso de software.

Marqué esta como la mejor solución, ya que funcionó perfectamente para mí. Codifiqué las marcas de tiempo en un archivo TXT y las agregué a una tarjeta SD junto con el archivo de audio (WAV). Este archivo TXT fue decodificado por la MCU, que luego inicializó un temporizador y leyó el archivo WAV de la tarjeta SD. Finalmente, el código comparó las marcas de tiempo con el contador de tiempo para activar lo que se necesitaba.

No me gusta codificar datos de comandos como una señal analógica en un archivo digital.

Creo que intentaría codificar los comandos de iluminación como bloques de texto en el bloque de letras de la información ID3 dentro del archivo mp3.

El bloque de letras está antes de los datos de sonido, por lo que debería poder decodificarlo rápidamente antes de comenzar la reproducción.

Las bibliotecas típicas para la reproducción de mp3 no parecen leer todas las etiquetas ID3. Algunas bibliotecas leen algunas etiquetas. Puede extraer las etiquetas de letras en su propia función de lectura antes de la reproducción o ampliar una de las bibliotecas existentes.

Dentro de las etiquetas de las letras, tienes marcas de tiempo y texto.

Puede codificar las marcas de tiempo como las definen los estándares ID3, o codificar sus propias marcas de tiempo más precisas en su propio formato (las marcas de tiempo ID3 solo se dan en segundos).

El contenido del texto es la parte interesante. Defina su propia codificación de texto para sus luces. Diga "DMX1:FFFF00000000" para una luz roja brillante completa en la dirección 1 (eso es solo codificar datos DMX como hexadecimales, con la dirección incluida en el encabezado).

O algo más simple si solo necesita encender y apagar un puñado de LED conectados directamente al microcontrolador.

O implemente su formato de modo que pueda usarlo para DMX, pero tenga un intérprete en su controlador para los LED locales.

El contenido realmente depende de ti. En cualquier caso, es mucho más flexible que incrustar sonidos en un canal de su archivo de audio.

Hay editores de letras que puede usar para poner sus comandos en los archivos mp3. Simplemente escriba los comandos en su formato privado como letras.

Este enfoque parece excelente, pero no puedo encontrar ninguna información sobre códecs (en IC, no en software) o bibliotecas que puedan decodificar letras ID3 (LYR) para poder recibir la marca de tiempo en tiempo real en la MCU... si hay cualquiera por favor hágamelo saber. :)
No está en el códec. Ha leído el archivo y ha extraído las etiquetas ID3. Como lo hace este proyecto ESP.
Ya veo, lástima que no hay mucha información sobre esto todavía. Pero esto ayuda, intentaré profundizar en eso y tal vez pueda encontrar un código. Gracias.
Su MCU tiene que leer el archivo y pasar los datos al decodificador de hardware. Simplemente extraiga el bloque de letras ID3 antes de comenzar a pasar bloques de datos al decodificador.

Una vez desarrollé una aplicación en la que eventos arbitrarios podían activarse mediante marcas de agua de audio incrustadas en el sonido. Podría reproducir el sonido a través de pequeños altavoces de computadora sin amplificar en un extremo de la mesa de la sala de conferencias, y mi caja de demostración ubicada en el otro extremo encendería los LED exactamente en los momentos correctos.

Era eficiente en el sentido de que el decodificador funcionaba con un pequeño microcontrolador de 8 bits (basado en 6502), respaldado por una cadena de procesamiento de señal analógica simple (preamplificador de micrófono, filtro, etc.)

¡Esto suena como un buen enfoque! ¿Puede proporcionar más información sobre el sistema que utilizó para codificar y decodificar las marcas de agua?
Lamentablemente no. El algoritmo es propiedad de Verance ; yo estaba trabajando para ellos en ese momento. Tendría que obtener una licencia de ellos o desarrollar el mismo concepto utilizando un algoritmo diferente.
Por extraño que parezca, construí el mismo tipo de cosa para otra persona usando una codificación casi ultrasónica. Pero no lo haría de esta manera por la necesidad del OP: controlan la reproducción desde la fuente de datos, por lo que no es necesario pasar por una cadena de audio. Si realmente quieren usar un decodificador IC distinto, solo detectar el inicio de la salida permitiría que las marcas de tiempo independientes funcionen, especialmente si la fuente del reloj se puede compartir.
@ChrisStratton: Sí, el enfoque de JRE es mejor en este caso. Solo quería poner una marca de agua en la mesa para las aplicaciones que necesitaban las señales incrustadas en el audio mismo.

La solución rápida en mi mundo sería reproducir desde una computadora. Hay programas de computadora listos que pueden sincronizar el sonido en muchos canales con Midi (normalmente usado para sintetizadores) o DMX (muy similar a Midi pero usado para luces).

Puede reproducir el MIDI simultáneamente en el esp32 y, como beneficio adicional, si asigna entradas de teclado MIDI a colores/luces específicos, puede crear y editar algunas pistas de referencia de iluminación bastante sólidas en el software de secuenciación MIDI de código abierto existente.
Sí, a través de la computadora es bastante fácil y lo he hecho muchas veces con Max MSP, pero el problema es que necesito usar esto con una MCU. Sin sistema operativo.