71歳の... 「vector コンテナ」でSD内のMP3ファイルをリストアップし、連続再生してみた

　```vector```コンテナを使ってみました。便利ですね。

https://github.com/earlephilhower/BackgroundAudio/blob/master/examples/NotSoSimpleMP3Shuffle/NotSoSimpleMP3Shuffle.ino

上記サイトを参考にしました。microSD内のMP３ファイルをサブディレクトリも含めリストアップし、連続再生してみました。ある程度の高音質ファイルも再生可能です。8.3形式のファイル名はもちろん、ロングファイルネームにも対応しているもよう。時々バグりますが。なお、上記サイトのようなランダム再生は、動作不良となりできませんでした。

||再生可能？|
|--|--|
|チャンネル|２（ステレオ）|
|サンプルレート|44.1 kHz|
|Bits Per Sample|16|
|ビットレート|128kbps|

再生中のシリアルモニタの表示です。

![LongName.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/d250ab0a-3450-4bd7-b328-349980ea7283.jpeg)
　環境や構成は以下になります。

:::note info
１．Windows 11 Pro
２．Arduino IDE 2.3.6
３．ESP32 Dev Module（Arduino IDE 内でのボード名）
４．SPI接続 microSDカードスロットモジュール
５．32GBまでの適当なmicroSDカード
６．PCM5102A使用 32bit/384kHz DAC モジュールhttps://store.shopping.yahoo.co.jp/nfj/h135.html
７．ボードマネージャは「esp32 by Espressif Systems version 3.0.1」にバージョンダウン
８．ツール > Partition Scheme:"Custom"（今回はこうしてみた）
９．ステレオミニジャックに外部アクティブスピーカーを接続。イヤホンを繋ぐ場合は音量（怨霊じゃないよ！）に注意してください。
:::
　スケッチです。

```c:SD_MP3_Player.ino
//***************************************************************
//*    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ファイルを突っ込んでおけば、ファイルに面倒な前処理を施さずとも、勝手に再生してくれるのかな？まだいろいろ試してはいません。最後まで見ていただきありがとうございました。