Chapter 31 Play SD card music
Note
The SD card chapter only applies to the ESP32 WROVER development board with an SD card slot on the back. If your ESP32 WROVER does not have an SD card slot on the back, please skip this chapter.
In the previous study, we have learned how to use the SD card, and then we will learn to play the music in the SD card.
Project 31.1 SDMMC Music
In this project, we will read an mp3 file from an SD card, decode it through ESP32, and use a speaker to play it.
Component List
|
|
|
|
|
|
|
|
|
|
|
|
Jumper F/M x4 Jumper F/F x2
|
|
||
Circuit
Schematic diagram |
|
Please note that before connecting the USB cable, please put the music into the SD card and insert the SD card into the card slot on the back of the ESP32.
|
Hardware connection If you need any support, please feel free to contact us via: support@freenove.com
|
Sketch
How to install the library
In this project, we will use the ESP8266Audio.zip library to decode the audio files in the SD card, and then output the audio signal through GPIO. If you have not installed this library, please follow the steps below to install it.
Open arduino -> Sketch -> Include library -> Add .ZIP Library.
In the new pop-up window, select “Freenove_Ultimate_Starter_Kit_for_ESP32\C\Libraries\ESP8266Audio.zip”.
Then click “Open”.
Sketch_31.1_PlayMP3FromSD
We placed a folder called “music” in:
Freenove_Ultimate_Starter_Kit_for_ESP32\Sketches\Sketch_31.1_PlayMP3FromSD
User needs to copy this folder to SD card.
Click upload.
Compile and upload the code to the ESP32 WROVER and open the serial monitor. ESP32 takes a few seconds to initialize the program. When you see the message below, it means that ESP32 has started parsing the mp3 in sd and started playing music through Pin.
The following is the program code:
1#include <Arduino.h>
2#include <WiFi.h>
3#include "FS.h"
4#include "SD_MMC.h"
5#include "AudioFileSourceSD_MMC.h"
6#include "AudioFileSourceID3.h"
7#include "AudioGeneratorMP3.h"
8#define IIS_ENABLE 0
9
10#ifdef IIS_ENABLE
11#include "AudioOutputI2S.h"
12#else
13#include "AudioOutputI2SNoDAC.h"
14#endif
15
16#define SD_MMC_CMD 15 //Please do not modify it.
17#define SD_MMC_CLK 14 //Please do not modify it.
18#define SD_MMC_D0 2 //Please do not modify it.
19#define I2S_BCLK 26
20#define I2S_DOUT 22
21#define I2S_LRC 25
22
23AudioGeneratorMP3 *mp3;
24AudioFileSourceID3 *id3;
25#ifdef IIS_ENABLE
26AudioOutputI2S *out;
27#else
28AudioOutputI2SNoDAC *out;
29#endif
30
31AudioFileSourceSD_MMC *file = NULL;
32
33// Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc.
34void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
35{
36 (void)cbData;
37 Serial.printf("ID3 callback for: %s = '", type);
38
39 if (isUnicode) {
40 string += 2;
41 }
42
43 while (*string) {
44 char a = *(string++);
45 if (isUnicode) {
46 string++;
47 }
48 Serial.printf("%c", a);
49 }
50 Serial.printf("'\n");
51 Serial.flush();
52}
53
54void setup()
55{
56 WiFi.mode(WIFI_OFF);
57 Serial.begin(115200);
58 delay(1000);
59 SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0);
60 if (!SD_MMC.begin("/sdcard", true, true, SDMMC_FREQ_DEFAULT, 5)) {
61 Serial.println("Card Mount Failed");
62 return;
63 }
64 Serial.printf("Sample MP3 playback begins...\n");
65
66 audioLogger = &Serial;
67 file = new AudioFileSourceSD_MMC("/music/01.mp3");
68 id3 = new AudioFileSourceID3(file);
69 id3->RegisterMetadataCB(MDCallback, (void*)"ID3TAG");
70 #ifdef IIS_ENABLE
71 out = new AudioOutputI2S();
72 #else
73 out = new AudioOutputI2SNoDAC();
74 #endif
75
76 out->SetPinout(I2S_BCLK,I2S_LRC,I2S_DOUT);//Set the audio output pin
77 out->SetGain(1.0);//Setting the Volume 0.1-3.9
78 mp3 = new AudioGeneratorMP3();
79 mp3->begin(id3, out);
80}
81
82void loop()
83{
84 if (mp3->isRunning()) {
85 if (!mp3->loop()) mp3->stop();
86 } else {
87 Serial.printf("MP3 done\n");
88 delay(1000);
89 }
90}
Add music decoding header files and SD card drive files.
If you want to use the circuit in 31.2, you just need to modify #define IIS_ENABLE 1.
1#include <Arduino.h>
2#include <WiFi.h>
3#include "FS.h"
4#include "SD_MMC.h"
5#include "AudioFileSourceSD_MMC.h"
6#include "AudioFileSourceID3.h"
7#include "AudioGeneratorMP3.h"
8#define IIS_ENABLE 0
9
10#ifdef IIS_ENABLE
11#include "AudioOutputI2S.h"
12#else
13#include "AudioOutputI2SNoDAC.h"
14#endif
Define the drive pins for SD card. Note that the SD card driver pins cannot be modified.
1#define SD_MMC_CMD 15 //Please do not modify it.
2#define SD_MMC_CLK 14 //Please do not modify it.
3#define SD_MMC_D0 2 //Please do not modify it.
4#define I2S_BCLK 26
5#define I2S_DOUT 22
6#define I2S_LRC 25
Apply for audio decoding class object.
1AudioGeneratorMP3 *mp3;
2AudioFileSourceID3 *id3;
3#ifdef IIS_ENABLE
4AudioOutputI2S *out;
5#else
6AudioOutputI2SNoDAC *out;
7#endif
8
9AudioFileSourceSD_MMC *file = NULL;
Set the audio file source and associate it with the decoder. Initialize the audio output pin and set the volume to 2.
1audioLogger = &Serial;
2file = new AudioFileSourceSD_MMC("/music/01.mp3");
3id3 = new AudioFileSourceID3(file);
4id3->RegisterMetadataCB(MDCallback, (void*)"ID3TAG");
5#ifdef IIS_ENABLE
6out = new AudioOutputI2S();
7#else
8out = new AudioOutputI2SNoDAC();
9#endif
10
11out->SetPinout(I2S_BCLK,I2S_LRC,I2S_DOUT);//Set the audio output pin
12out->SetGain(1.0);//Setting the Volume 0.1-3.9
13mp3 = new AudioGeneratorMP3();
14mp3->begin(id3, out);
Determine whether the mp3 player is finished. If it is playing, continue playing. If it is finished, print a message.
1if (mp3->isRunning()) {
2 if (!mp3->loop()) mp3->stop();
3} else {
4 Serial.printf("MP3 done\n");
5 delay(1000);
6}
Project 31.2 SDMMC Music
In this project, we will read mp3 files from SD card, decode them through ESP32, and use Audio Converter & Amplifier module to transcode into stereo output.
Component List
|
|
|
|
Audio Converter & Amplifier |
|
|
Card reader x1 (random color)
(Not a USB flash drive.) |
|
Circuit
Schematic diagram |
|
Please note that before connecting the USB cable, please put the music into the SD card and insert the SD card into the card slot on the back of the ESP32.
|
Hardware connection If you need any support, please feel free to contact us via: support@freenove.com
|
Sketch
How to install the library
In this project, we will use the ESP32-audioI2S.zip library to decode the audio files in the SD card, and then output the audio signal through IIS. If you have not installed this library, please follow the steps below to install it.
Open arduino -> Sketch -> Include library -> Add .ZIP Library.
In the new pop-up window, select “Freenove_Ultimate_Starter_Kit_for_ESP32\C\Libraries\ESP32-audioI2S.zip”.
Then click “Open”.
Sketch_31.2_SDMMC_Music
We placed a folder called “music” in:
Freenove_Ultimate_Starter_Kit_for_ESP32\Sketches\Sketch_31.2_SDMMC_Music.
User needs to copy this folder to SD card.
Click Tools -> Partition Scheme, Select Huge APP……, Then click upload.
Compile and upload the code to the ESP32 WROVER and open the serial monitor. ESP32 takes a few seconds to initialize the program.
When you see the message below, it means that ESP32 has started parsing the mp3 in sd and started playing music through iis.
The following is the program code:
1/**********************************************************************
2 Filename : SDMMC Music
3 Description : Play music from the sd card.
4 Auther : www.freenove.com
5 Modification: 2024/06/20
6**********************************************************************/
7#include "Arduino.h"
8#include "Audio.h"
9#include "FS.h"
10#include "SD_MMC.h"
11
12#define SD_MMC_CMD 15
13#define SD_MMC_CLK 14
14#define SD_MMC_D0 2
15#define I2S_BCLK 26
16#define I2S_DOUT 22
17#define I2S_LRC 25
18
19Audio audio;
20
21void setup() {
22 Serial.begin(115200);
23
24 SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0);
25 if (!SD_MMC.begin("/sdcard", true, true, SDMMC_FREQ_DEFAULT, 5)) {
26 Serial.println("Card Mount Failed");
27 return;
28 }
29 uint8_t cardType = SD_MMC.cardType();
30 if (cardType == CARD_NONE) {
31 Serial.println("No SD_MMC card attached");
32 return;
33 }
34 if (cardType == CARD_MMC) {
35 Serial.println("MMC");
36 } else if (cardType == CARD_SD) {
37 Serial.println("SDSC");
38 } else if (cardType == CARD_SDHC) {
39 Serial.println("SDHC");
40 } else {
41 Serial.println("UNKNOWN");
42 }
43 uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
44 Serial.printf("SD_MMC Card Size: %lluMB\n", cardSize);
45
46 audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
47 audio.setVolume(12); // 0...21
48
49 audio.connecttoFS(SD_MMC, "/music/01.mp3");
50}
51
52void loop() {
53 audio.loop();
54 if (Serial.available()) { // put streamURL in serial monitor
55 audio.stopSong();
56 String r = Serial.readString();
57 r.trim();
58 if (r.length() > 5) audio.connecttoFS(SD_MMC, r.c_str());
59 log_i("free heap=%i", ESP.getFreeHeap());
60 }
61}
62
63// optional
64void audio_info(const char *info) {
65 Serial.print("info ");
66 Serial.println(info);
67}
68void audio_id3data(const char *info) { //id3 metadata
69 Serial.print("id3data ");
70 Serial.println(info);
71}
72void audio_eof_mp3(const char *info) { //end of file
73 Serial.print("eof_mp3 ");
74 Serial.println(info);
75}
76void audio_showstation(const char *info) {
77 Serial.print("station ");
78 Serial.println(info);
79}
80void audio_showstreamtitle(const char *info) {
81 Serial.print("streamtitle ");
82 Serial.println(info);
83}
84void audio_bitrate(const char *info) {
85 Serial.print("bitrate ");
86 Serial.println(info);
87}
88void audio_commercial(const char *info) { //duration in sec
89 Serial.print("commercial ");
90 Serial.println(info);
91}
92void audio_icyurl(const char *info) { //homepage
93 Serial.print("icyurl ");
94 Serial.println(info);
95}
96void audio_lasthost(const char *info) { //stream URL played
97 Serial.print("lasthost ");
98 Serial.println(info);
99}
Add music decoding header files and SD card drive files.
1#include "Arduino.h"
2#include "Audio.h"
3#include "FS.h"
4#include "SD_MMC.h"
Define the drive pins for SD card and IIS. Note that the SD card driver pins cannot be modified, but the IIS drive pins can be modified.
1#define SD_MMC_CMD 15
2#define SD_MMC_CLK 14
3#define SD_MMC_D0 2
4#define I2S_BCLK 26
5#define I2S_DOUT 22
6#define I2S_LRC 25
Declare an audio decoding object, associate it with the pin, set the volume, and set the decoding object.
1Audio audio;
2......
3audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
4audio.setVolume(12); // 0...21
5audio.connecttoFS(SD_MMC, "/music/Jingle Bells.mp3");
Play music until one piece of music finishes playing. If the serial port receives data, it will call the audio object to decode it after removing the spaces at the head and tail of the data.
1audio.loop();
2if (Serial.available()) { // put streamURL in serial monitor
3 audio.stopSong();
4 String r = Serial.readString();
5 r.trim();
6 if (r.length() > 5) audio.connecttoFS(SD_MMC, r.c_str());
7 log_i("free heap=%i", ESP.getFreeHeap());
8}
In other words, if you want to switch the music in the SD card, you can directly input the song through the serial port.
1audio.loop();
2if (Serial.available()) { // put streamURL in serial monitor
3 audio.stopSong();
4 String r = Serial.readString();
5 r.trim();
6 if (r.length() > 5) audio.connecttoFS(SD_MMC, r.c_str());
7 log_i("free heap=%i", ESP.getFreeHeap());
8}
The following functions are used to print the audio decoding information. If you do not want to see the decoding information in the serial port, you can directly comment out these functions.
1void audio_info(const char *info);
2void audio_id3data(const char *info);
3void audio_eof_mp3(const char *info);
4void audio_showstation(const char *info);
5void audio_showstreamtitle(const char *info);
6void audio_bitrate(const char *info);
7void audio_commercial(const char *info);
8void audio_icyurl(const char *info);
9void audio_lasthost(const char *info);

















