本程序不能在ESP32芯片上很好地运行,经过仔细地排查,问题在于ESP32的运行内存太小( SRAM 有 520KB,但是系统启动后可用内存约为 300KB),导致处理音频文件时,定义的全局变量musicList被覆盖(向屏幕打印显示乱码了)
显示歌曲列表,可切换和暂停
#include <M5Stack.h> #include "FS.h" #include "AudioFileSourceSD.h" #include "AudioFileSourceID3.h" #include "AudioGeneratorMP3.h" #include "AudioOutputI2S.h" AudioGeneratorMP3 *mp3; AudioFileSourceSD *file; AudioOutputI2S *out; AudioFileSourceID3 *id3; bool myplay = false; int i=0; int current_i = -1; char* musicList[4]; void listFile(fs::FS &fs, const char * dirname){ File root = fs.open(dirname); if(!root){ M5.Lcd.print("Failed to open directory"); return; } if(!root.isDirectory()){ M5.Lcd.print("Not a directory"); return; } File file = root.openNextFile(); while(file){ if(!file.isDirectory()){ musicList[i] = (char*)file.name(); i++; //M5.Lcd.println(file.name()); } file = root.openNextFile(); } } void setup(){ M5.begin(); M5.Lcd.setTextSize(2); listFile(SD,"/"); M5.Lcd.setTextWrap(false,false); for(i=0;i<3;i++){ M5.Lcd.setCursor(0,15*i); M5.Lcd.print(musicList[i]); } M5.Lcd.fillRect(300,4,10,10,RED); i = 0; M5.Lcd.setCursor(0,220); } void loop(){ M5.update(); if (myplay&&mp3&&mp3->isRunning()) { if (!mp3->loop()) mp3->stop(); } if(M5.BtnB.wasPressed()){//切换至下一曲 M5.Lcd.fillRect(300,4+15*i,10,10,BLACK); i = (++i)%3; if(i == current_i){ if(myplay){ M5.Lcd.fillRect(300,4+15*i,10,10,GREEN); }else{ M5.Lcd.fillRect(300,4+15*i,10,10,YELLOW); } }else{ M5.Lcd.fillRect(300,4+15*i,10,10,RED); } } if(M5.BtnC.wasPressed()){ if(current_i == i){ if(myplay){ myplay = myplay^true;//暂停播放 out->flush(); M5.Lcd.fillRect(300,4+15*(i),10,10,YELLOW); }else{ if(mp3&&mp3->isRunning()){//恢复播放 myplay = myplay^true; M5.Lcd.fillRect(300,4+15*(i%3),10,10,GREEN); } } } else{ M5.Lcd.drawNumber(i,0,200); myplay = true; if(mp3&&mp3->isRunning()){ mp3->stop(); } M5.Lcd.drawString(musicList[i],0,220,1); file = new AudioFileSourceSD(musicList[i]); id3 = new AudioFileSourceID3(file); out = new AudioOutputI2S(0, 1); // Output to builtInDAC out->SetOutputModeMono(true); mp3 = new AudioGeneratorMP3(); mp3->begin(id3, out); M5.Lcd.fillRect(300,4+15*i,10,10,GREEN); current_i = i; } } }
1.仅仅播放了一首歌,第二首歌的相关对象还没new出来,musicList已经被覆盖了
2.或许可以把flash memory扩展成内存;或者少定义变量,存储一些中间文件到json中
3.尽快实现通信,远程控制