reproducir_sonido_con_esp32
Diferencias
Muestra las diferencias entre dos versiones de la página.
reproducir_sonido_con_esp32 [2025/04/04 14:39] – creado hispa | reproducir_sonido_con_esp32 [Fecha desconocida] (actual) – editor externo (Fecha desconocida) 127.0.0.1 | ||
---|---|---|---|
Línea 1: | Línea 1: | ||
+ | ~~NOTOC~~ | ||
+ | <WRAP round box> | ||
+ | ====== Reproducir sonido con ESP32 ====== | ||
+ | </ | ||
+ | <WRAP tabs> | ||
+ | * [[ESP32]] | ||
+ | * [[DConectar ESP32 al WiFi con MicroPython|Anterior: | ||
+ | </ | ||
+ | <WRAP collarge justify> | ||
+ | ==== Introducción ==== | ||
+ | |||
+ | Hoy vamos a ver una de las cosas más chulas que he aprendido hasta el momento del ESP32, una maquinita que nunca deja de sorprenderme no sólo por su velocidad y capacidad de memoria, sino también por detalles como el que voy a tratar de explicar a continuación. | ||
+ | |||
+ | Aunque siempre me he declarado un enamorado de los ESP8266, tengo que reconocer que por un pequeño coste casi imperceptible, | ||
+ | |||
+ | ¿Y qué narices es eso de «DAC»? Pues fácil: son las siglas de «Digital to Analog Converter», | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | El montaje, como se puede ver, no puede ser más simple. Sólo necesitamos el ESP32 y un altavoz pequeño de 8 Ohm. Si queremos aumentar el volumen podemos incluir un amplificador, | ||
+ | |||
+ | ==== Limitaciones de espacio del ESP32 ==== | ||
+ | |||
+ | Los microcontroladores ESP32, además de una memoria interna de unos 500KB para almacenar programas y datos, disponen de una memoria flash «externa» (aunque la mayoría de las veces la encontraréis «incrustada» en la propia placa del controlador) que puede llegar hasta los 16MB. En modelos de última generación esta memoria incluso puede ser mucho mayor, pero nos centraremos en los modelos convencionales y que pueden encontrarse en cualquier tienda online. | ||
+ | |||
+ | Lo normal, por economía, es tener algún ESP32 con 4MB de flash, así que los datos de sonido que queramos reproducir deben caber en este espacio. Como además estamos hablando de sonido sin comprimir, sólo disponemos de algunos segundos de reproducción, | ||
+ | |||
+ | Pero para ello primero debemos trabajar un poco con el archivo de sonido. Usaremos un archivo mp3, lo convertiremos a wav, eliminando con ello la compresión, | ||
+ | |||
+ | ==== Convertir sonido a archivo wav ==== | ||
+ | |||
+ | Para convertir el archivo mp3 a wav utilizaremos la aplicación «Audacity», | ||
+ | {{ : | ||
+ | Con «Archivo - Abrir» seleccionamos el archivo de sonido sobre el que vamos a trabajar (que en mi caso va a ser un mp3 de Los Beatles). Al cargarse el archivo, la pantalla de Audacity se vería así: | ||
+ | {{ : | ||
+ | Como he explicado antes, la memoria interna del ESP32 no permite cargar una canción descomprimida completa por falta de espacio, así que seleccionamos unos diez segundos de canción pulsando dentro del espectro de sonido y arrastrando el ratón hasta la marca deseada: | ||
+ | {{ : | ||
+ | Copiamos con CTRL+C (copiar), y selecionamos «Archivo - Nuevo», con lo que se nos abre una nueva ventana vacía de Audacity. Allí pulsamos CTRL+V (pegar). Con esto tendremos el intervalo de sonido que queremos reproducir en una ventana aparte. | ||
+ | |||
+ | Para ver el espectro completo de la selección pulsamos CTRL+F, y podemos cortar el tiempo se silencio del principio con CTRL+X. Ahora Audacity aparecerá de esta forma: | ||
+ | {{ : | ||
+ | Como se puede ver, es un sonido en estéreo, con un canal derecho y otro izquierdo, y aunque el ESP32 dispone de dos canales DAC, en principio sólo queremos reproducir el sonido por uno de ellos, aunque sólo sea por simplificar el montaje electrónico necesario, así que mezclaremos ambos canales en Audacity con «Pistas - Mezclar - Mezclar pista estéreo a mono». Eso dejará la ventana de Audacity como se ve en la siguiente imagen: | ||
+ | {{ : | ||
+ | Ahora, y para que podamos oír el audio con el mejor volumen posible, amplificamos la muestra con «Seleccionar - Todo» y «Efecto - Amplificar». Dejando los valores que Audacity propone por defecto obtendremos un sonido de más amplitud sin distorsiones. Con «Aceptar», | ||
+ | {{ : | ||
+ | Sin embargo, todavía nos queda un poco más de trabajo con este trocito de audio. En primer lugar, debemos cambiar la frecuencia de muestreo de 44100Hz a 16000Hz, cosa que se puede hacer fácilmente con el selector de abajo a la izquierda. | ||
+ | |||
+ | Finalmente, grabaremos el audio en un wav con «Archivo - Exportar - Exportar como WAV», especificando en la codificación «Unsigned 8 bits PCM». (Como hemos visto antes, los canales DAC del ESP32 son de 8 bits, por lo tanto necesitamos que los datos que le enviemos también lo sean. Esto irá en detrimento de la calidad del sonido, pero es lo que hay) | ||
+ | {{ : | ||
+ | Como no es necesario añadir metadatos al archivo, basta con aceptar y ya tendremos nuestro archivo «prueba.wav» en la carpeta que hayamos elegido. En mi caso, el tamaño del archivo es de 206KB, lo que no es excesivo, pero hay que tener en cuenta que sólo son unos segundos. | ||
+ | |||
+ | ==== Convertir archivo wav a array de datos ==== | ||
+ | |||
+ | Ahora necesitamos convertir ese archivo de audio (en mi caso, «prueba.wav») a una matriz de datos que el ESP32 sea capaz de leer. Para ello utilizaré el programa «ImHex», disponible en los repositorios de Linux Mint, aunque hay otros tanto para Linux como para Windows que pueden realizar el mismo trabajo. | ||
+ | {{ : | ||
+ | Con «File - Open file» seleccionaremos nuestra muestra de audio. Eso hará que la ventana del programa aparezca como en la siguiente imagen: | ||
+ | {{ : | ||
+ | Pinchamos sobre el primer dato hexadecimal, | ||
+ | {{ : | ||
+ | Con esto tendremos en nuestro portapapeles los datos de la muestra de audio como un array de datos formateado para el lenguaje C usado por la ESP32. Es hora de abrir el IDE de Arduino. | ||
+ | |||
+ | ==== Preparar el archivo auxiliar de datos de sonido ==== | ||
+ | |||
+ | Abierto el IDE de Arduino, y [[https:// | ||
+ | {{ : | ||
+ | Ahora podemos pegar ahí nuestros datos copiados desde ImHex, ya sea con «Editar - Pegar» o con «CTRL+V». Esto nos dejará más de 12.000 líneas de datos en el archivo, que ahora aparecerá más o menos así: | ||
+ | {{ : | ||
+ | Ahora ya tenemos nuestros datos listos para ser invocados por el programa que reproducirá el sonido. Este programa utilizará la librería XT_DAC_Audio, | ||
+ | |||
+ | ==== Librería XT_DAC_Audio, | ||
+ | |||
+ | La librería XT_DAC_Audio se puede descargar desde la página de su autor (https:// | ||
+ | |||
+ | XT_DAC_Audio es una librería bastante potente, que puede leer gran multitud de cadenas de audio y reproducirlas de diferentes maneras, cambiando su velocidad, volumen, generando listas de reproducción, | ||
+ | |||
+ | ==== Programa de ejemplo ==== | ||
+ | |||
+ | Las dos primeras líneas de nuestro programa de ejemplo invocarán a las librerías necesarias: | ||
+ | |||
+ | <code c> | ||
+ | #include " | ||
+ | #include < | ||
+ | </ | ||
+ | |||
+ | Ahora creamos dos objetos, uno de la clase XT_Wav_Class (// | ||
+ | |||
+ | <code c> | ||
+ | XT_Wav_Class hey_jude(data); | ||
+ | XT_DAC_Audio_Class DacAudio(25, | ||
+ | </ | ||
+ | |||
+ | A continuación, | ||
+ | |||
+ | <code c> | ||
+ | void setup() { | ||
+ | hey_jude.Speed = 1; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Finalmente, en la función loop() (que es la que se repite de forma continua en el ESP32), lo primero que ordenamos al objeto que gestiona el sonido es que llene su buffer de datos, una memoria intermedia entre nuestros datos y el exterior que garantiza la estabilidad del sonido que se va a producir. Lo hacemos en cada inicio del bucle, de manera que este buffer esté siempre lleno. | ||
+ | |||
+ | Lo siguiente es un condicional para saber si nuestro sonido se está reproduciendo o no, y si no se está reproduciendo, | ||
+ | |||
+ | <code c> | ||
+ | void loop() { | ||
+ | DacAudio.FillBuffer(); | ||
+ | if(hey_jude.Playing==false) | ||
+ | DacAudio.Play(& | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | El sketch completo quedaría así: | ||
+ | |||
+ | <code c++> | ||
+ | #include " | ||
+ | #include < | ||
+ | |||
+ | XT_Wav_Class hey_jude(data); | ||
+ | XT_DAC_Audio_Class DacAudio(25, | ||
+ | |||
+ | void setup() { | ||
+ | hey_jude.Speed = 1; | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | DacAudio.FillBuffer(); | ||
+ | if(hey_jude.Playing==false) | ||
+ | DacAudio.Play(& | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Esto, claro, es un ejemplo básico de cómo reproducir sonido con el ESP32, pero como he comentado, la librería XT_DAC_Audio es mucho más potente, y os invito a estudiarla para sacar todo el provecho posible al sonido de vuestros microcontroladores ESP32. | ||
+ | |||
+ | {{ vid_20230610_103025.mp4? | ||
+ | \\ | ||
+ | \\ | ||
+ | </ | ||
+ | |||
+ | {{tag> cacharreo C++ ESP32}} | ||