Diseñar una interfaz de usuario para un reproductor de musica basado en un ESP32 con LVGL


En este post, vamos a ver una guia creada por @moononournation, que nos muestra cómo usar LVGL y SquareLine Studio para diseñar una interfaz de usuario de reproductor de música estilo Winamp. LVGL es una biblioteca de gráficos para crear fácilmente una interfaz gráfica de usuario elegante y SquareLine Studio ayuda a reducir la cantidad de codificación requerida para usar LVGL

En este post vamos a ver como implementar un reproductor casero al mas puro estilo winamp de forma completamente personalizable. Para ello cualquier dispositivo de desarrollo ESP32 con pantalla y salida de audio debería estar bien.

A continuación se muestran algunos dispositivos usados:

  • Por ultimo una opción con pantalla mas grande es el módulo ESP32-S3-pantalla inteligente HMI 8M PSRAM 16M Flash Arduino LVGL WIFI y Bluetooth 7 «800×480, módulo TFT LCD RGB de 7,0 pulgada ( mas información en eHttps://www.aliexpress.com/item/1005004952726089.html).

Diseño de interfaz de usuario

Puede usar varias formas de pantalla, redonda, cuadrada, rectangular. Es mejor determinar usar qué forma primero. Luego, el siguiente paso es determinar cómo se ve la interfaz de usuario.

Reproductor de música clásica

Reproductor de música clásica
Reproductor de música clásica
Reproductor de música clásica
Reproductor de música clásica

Si aún no tiene ninguna idea de diseño de interfaz de usuario, imitar un reproductor de música clásico puede ser un buen comienzo.

Winamp es un reproductor de música de escritorio clásico de Windows que apareció en el siglo pasado, luego mas tarde hubo una variante de interfaz de usuario similar con soporte de caracteres chinos llamada TTPlayer . Estas 2 aplicaciones son el recuerdo de la infancia de muchos aficionados (y también el de muchas personas), así que usaremos esas UI como plantilla de diseño.

Winamp está diseñado para cambiar la «máscara» fácilmente, y los recursos de imagen de la máscara están en formato BMP empaquetados en un archivo zip. Puede encontrar una gran colección de máscaras de Winamp en skins.webamp.org , por lo que es fácil acceder a su máscara de Winamp favorita como plantilla de diseño.

Puede encontrar cómo iniciar el diseño de la interfaz de usuario desde la máscara de Winamp en bilibili:

https://www.bilibili.com/video/BV1ia4y137KM/

El reproductor de música tiene varias funciones, pero el autor del git esta interesado en las características que se encuentran en Winamp o TTPlayer. 

Aquí está la lista de deseos de funciones muchas ya implementadas en el actual firmware disponible en el git:

  • Reproducir MP3 desde la tarjeta SD
  • Lista de archivos MP3 de la tarjeta SD
  • Mostrar caracteres Unicode
  • Operación de reproducción básica (reproducir, pausar, detener, anterior y siguiente)
  • Control del volumen
  • Mostrar información MP3 ID3
  • Mostrar imagen de portada de MP3
  • Mostrar letras MP3
  • Sincroniza la visualización de letras mientras juegas
  • Mostrar analizador de espectro de audio

Reproducir MP3 desde la tarjeta SD

Al principio, necesitamos una biblioteca de audio que pueda leer archivos MP3 desde la tarjeta SD y reproducirlos. Esta vez usaremos ESP32-audioI2S. Es compatible con la familia ESP32, lee archivos de audio de varias fuentes y reproduce la salida al módulo I2S. 

Puede encontrar más detalles en Github:

https://github.com/schreibfaul1/ESP32-audioI2S.git

Operación de reproducción básica

Operación básica de reproducción

ESP32-audioI2S proporcionó toda la API de reproducción básica, solo necesitamos crear todos los widgets de botón correspondientes para cada operación. Sin embargo, el diseño del botón original de Winamp es demasiado pequeño para operar en la pantalla táctil con el dedo. Así que amplié un poco los botones y también extiendo un poco el área táctil con un fondo transparente.

Para cada botón, asigne el widget de botón a una función correspondiente.

Utilice el botón de reproducción como ejemplo:

lv_obj_add_event_cb(ui_ButtonPlay, playSong, LV_EVENT_CLICKED, NULL);

Y luego, en la función playSong, llame a la API ESP32-audioI2S:

void playSong(lv_event_t *e) 
{
if (isPlaying)
{
audio.pauseResume();
}
más
{
play_selected_song();
}
}

Enumeración de los archivos MP3 de la tarjeta SD

Antes de decirle a ESP32-audioI2S que reproduzca el archivo MP3, primero debemos buscar y enumerar los archivos MP3 de la tarjeta SD. Aquí está el extracto del código de read_song_list() que ilustra cómo concatenar la cadena de la lista de canciones separada por el carácter de salto de línea (\n):

Raíz del archivo = SD_MMC.open("/"); 
Archivo archivo = root.openNextFile();
while (archivo)
{
 if (archivo.isDirectory())
  {
   Serial.printf("DIR: %s\n", archivo.nombre());
  }
  else
  {
   const char *nombre de archivo = archivo.nombre();

   int8_t len ​​= strlen(nombre de archivo);
   const char *MP3_EXT = ".mp3";
   if ((nombre de archivo[0] != '.') && (strcmp(MP3_EXT, &nombre de archivo[len - 4]) == 0)) { // Serial.printf("
   Archivo
    de canción: %s, tamaño: %d\ n", nombre de archivo, archivo.tamaño());
    if (cuenta_canciones > 0)
    {
     stringSongList += '\n';
    }
    stringSongList += nombre de archivo;
    cuenta_canciones++;
   }
  }
  archivo = root.openNextFile();
}

Luego asigne la cadena de lista de canciones concatenada al componente de rodillo LVGL:

lv_roller_set_options(ui_RollerPlayList, stringSongList.c_str(), LV_ROLLER_MODE_INFINITE);

Mostrar caracteres Unicode

Mostrar caracteres Unicode

La compatibilidad con LVGL muestra caracteres Unicode, pero requiere un archivo de fuente Unicode. 

Control de volumen

Control del volumen

Asigne el control deslizante de volumen a una función de evento de cambio de valor:

lv_obj_add_event_cb(ui_ScaleVolume, volumenCambiado, LV_EVENT_VALUE_CHANGED, NULL);

Y luego, en la función de evento, llame a la API ESP32-audioI2S:

void volumenCambiado(lv_event_t *e) 
{
int16_t volumen = lv_slider_get_value(ui_ScaleVolume);
audio.setVolume(volumen);
}

La interfaz de usuario de progreso de tiempo también es un widget deslizante. Pero está demasiado cerca de los botones y la interfaz de usuario de control de volumen, por lo que deshabilité la entrada táctil para evitar una operación inesperada.Agregar sugerenciaPreguntaComentarioDescargar

Mostrar la información MP3 ID3

ESP32-audioI2S expuso una función de devolución de llamada audio_id3data(). La función es llamada para cada etiqueta ID3 que se encuentra en el archivo MP3.

En la función de devolución de llamada, simplemente concatene todos los datos en una cadena:

if (playingStr.length() > 0) 
{
playingStr += " ";
}
jugandoStr += info;

Luego asigne a una etiqueta para mostrar:

lv_label_set_text(ui_LabelPlaying, playingStr.c_str());

Mostrar una imagen de portada de MP3

ESP32-audioI2S expuso una función de devolución de llamada audio_id3image(). Se llama a la función si se encuentra una imagen de portada en la etiqueta MP3 ID3. La imagen puede ser cualquier formato de imagen, actualmente en soporte para decodificar y mostrar un archivo de imagen JPEG no progresivo.

En la función de devolución de llamada, copie los datos binarios:

archivo.buscar(pos); 
archivo.leer(coverImgFile, len);

Busque el encabezado JPEG:

tamaño_t idx = 11; 
while ((idx < len) && ((coverImgFile[idx++] != 0xFF) || (coverImgFile[idx] != 0xD8)))
;
--idx;

Luego decodifica con JPEGDEC:

jpegdec.openRAM(coverImgFile + idx, len - idx, jpegDrawCallback);

Agregar sugerenciaPreguntaComentarioDescargar

Mostrar las letras de las canciones en MP3

ESP32-audioI2S expuso una función de devolución de llamada audio_id3lyrics(). Se llama a la función si se encuentran letras sincronizadas, letras no sincronizadas o etiquetas de datos de texto en un archivo MP3.

En la función de devolución de llamada, copie los datos binarios:

archivo.buscar(pos); 
file.read((uint8_t *)lyricsText, len);

Decodificar texto binario a UTF8:

audio.unicode2utf8(letraTexto, largo);

Si el texto tiene una etiqueta de tiempo de sincronización, almacene el índice de tiempo en la matriz syncTimeLyricsSec[] y syncTimeLyricsLineIdx[].

Luego configure el texto de la letra en el widget de rodillo:

lv_roller_set_options(ui_RollerLyrics, lyricsText, LV_ROLLER_MODE_NORMAL);

Agregar sugerenciaPreguntaComentarioDescargar

Sincronizar las letras de la pantalla mientras se reproduce

Si se encuentra la etiqueta de letras sincronizadas, haga rodar el widget de letras mientras juega:

for (int i = 0; i < syncTimeLyricsCount; ++i) 
{
if (syncTimeLyricsSec[i] == currentTime)
{
lv_roller_set_selected(ui_RollerLyrics, syncTimeLyricsLineIdx[i], LV_ANIM_ON);
romper;
}
}

Mostrar analizador de espectro de audio

ESP32-audioI2S también expuso una función de devolución de llamada audio_process_i2s() para procesar la salida de audio. Podemos utilizar esta función para recopilar los datos de audio para visualizar el espectro de audio.

En la función de devolución de llamada, recopile los datos de audio:

raw_data[raw_data_idx++] = *muestra;

Si los datos están llenos, procese con la clase FFT:

if (raw_data_idx >= WAVE_SIZE) 
{
fft.exec((int16_t *)raw_data);
dibujar_fft_nivel_metro(canvasFFT_gfx);
lv_obj_invalidate(ui_CanvasFFT);
raw_data_idx = 0;
}

Nota: La visualización se dibuja en un lienzo, canvasFFT_gfx, por separado. Y el lienzo está asociado con el widget ui_CanvasFFT de LVGL.

Opcional: Carcasa

Un hermoso estuche para el dispositivo de desarrollo puede hacer que se parezca más a un reproductor de música.

Puede encontrar el estuche de escritorio WT32-SC01 PLUS en Thingiverse y luego imprimirlo en el color que le guste ( https://www.thingiverse.com/thing:6030590 )

Por cierto , todas las fuentes de imágenes, los proyectos de SquareLine Studio y el código fuente se pueden encontrar en Github:

https://github.com/moononournation/LVGL_Music_Player.git

Fuente: https://www.instructables.com/Design-Music-Player-UI-With-LVGL/?utm_source=newsletter&utm_medium=email

Anuncio publicitario

Deja una respuesta

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.