vector
コンテナを使ってみました。便利ですね。
上記サイトを参考にしました。microSD内のMP3ファイルをサブディレクトリも含めリストアップし、連続再生してみました。ある程度の高音質ファイルも再生可能です。8.3形式のファイル名はもちろん、ロングファイルネームにも対応しているもよう。時々バグりますが。なお、上記サイトのようなランダム再生は、動作不良となりできませんでした。
再生可能? | |
---|---|
チャンネル | 2(ステレオ) |
サンプルレート | 44.1 kHz |
Bits Per Sample | 16 |
ビットレート | 128kbps |
再生中のシリアルモニタの表示です。
1.Windows 11 Pro
2.Arduino IDE 2.3.6
3.ESP32 Dev Module(Arduino IDE 内でのボード名)
4.SPI接続 microSDカードスロットモジュール
5.32GBまでの適当なmicroSDカード
6.PCM5102A使用 32bit/384kHz DAC モジュールhttps://store.shopping.yahoo.co.jp/nfj/h135.html
7.ボードマネージャは「esp32 by Espressif Systems version 3.0.1」にバージョンダウン
8.ツール > Partition Scheme:"Custom"(今回はこうしてみた)
9.ステレオミニジャックに外部アクティブスピーカーを接続。イヤホンを繋ぐ場合は音量(怨霊じゃないよ!)に注意してください。
スケッチです。
//***************************************************************
//* audioI2S-- I2S audiodecoder for ESP32, *
//***************************************************************
#include "Audio.h"
#include "SD.h"
#include <vector>
#include <string.h>
#define SPI_MOSI 23
#define SPI_MISO 19
#define SPI_SCK 18
#define SD_CS 5
#define I2S_DOUT 25
#define I2S_BCLK 27
#define I2S_LRC 26
Audio audio;
// List of all MP3 files in the root directory
std::vector<String> mp3list;
// The file we're currently playing
File f;
long nmax;
// Recursively scan the card and make a list of all MP3 files
// in all dirs
void scanDirectory(const char *dirname) {
File root = SD.open(dirname);
while (true) {
f = root.openNextFile();
if (!f) {
break;
}
String n = f.name();
n.toLowerCase();
String path = dirname;
path += f.name();
if (f.isDirectory()) {
if (f.name()[0] == '.') {
// Ignore . and ..
continue;
}
String sub = dirname;
sub += f.name();
sub += "/";
scanDirectory(sub.c_str());
} else if (strstr(n.c_str(), ".mp3")) {
mp3list.push_back(path);
Serial.printf("ADD: %s\n\r", path.c_str());
} else {
//Serial.printf("SKP: %s\n\r", path.c_str());
}
f.close();
}
root.close();
}
void setup() {
Serial.begin(115200);
SD.begin(SD_CS, SPI, 48000000, "/sd"); //24000000
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(6); // 0...21
scanDirectory("/");
Serial.println("Mp3 List ----------");
nmax = mp3list.size();
for (int i = 0; i < nmax; i++) Serial.println(mp3list[i].c_str());
Serial.println("-------------------");
}
//char song[14];
long n = -1;
int err = 0;
void loop() {
if (err < 10 && n < nmax) { // 5回のファイルエラーで空白ループに移行
audio.loop();
if (!audio.isRunning()) {
n++;
//sprintf(song,"track%03d.mp3",n);
if (!audio.connecttoFS(SD, mp3list[n].c_str())) {
n++;
err++;
}
}
}
}
// optional
//const char* str="MP3 decode error";
const char *str = "End of file";
void audio_info(const char *info) {
Serial.print("info ");
Serial.println(info);
//std::string str(*info,11,15);
if (strncmp(info, str, 10) == 0) {
Serial.println("\n\r----------------------------------------");//err++;
}
}
void audio_eof_mp3(const char *info) { //end of file
Serial.print(" --- eof_mp3 ");
Serial.println(info);
}
/*
void audio_id3data(const char *info){ //id3 metadata
Serial.print("id3data ");Serial.println(info);
}
*/
ルート・サブディレクトリ関係なくSDカードにMP3ファイルを突っ込んでおけば、ファイルに面倒な前処理を施さずとも、勝手に再生してくれるのかな?まだいろいろ試してはいません。最後まで見ていただきありがとうございました。