MP3 playback direct from SD card on XIAO 52840

Just wondering if anybody here has experience with or knowledge of decoding MP3 files.

I’ve found this library GitHub - TMRh20/microDecoder: Decode Audio files using Arduino which I adapted slightly to work.
Using that library, I’ve been able to successfully play back MP3 files on my nRF52840 based devices directly from SD card.

The MP3 decoding library is a bit limited in features and functionality, but it does work! I’m looking for a more fully featured lib or codebase that is actively maintained. Google isn’t helping much.

Working proof of concept code is below: (uses my AutoAnalogAudio library & I2S amp MAX98357A)

#include <SD.h>
#include <AutoAnalogAudio.h>
#include "mp3.h"  // decoder
#include "pcm.h"

mp3 MP3;
pcm audio;
AutoAnalog aaAudio;

const char* audioFilename = "noceil.mp3";
uint8_t SD_CS_PIN = 5;                      // Set this to your CS pin for the SD card/module
#define USE_I2S 1

char songName[64];
float volumeControl = 0.2;
#define AUDIO_BUFFER_SIZE 6400

void setup() {

  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  pinMode(6, OUTPUT);  //Connected to SD pin of MAX98357A
  digitalWrite(6, HIGH);

  Serial.begin(115200);
  while (!Serial) delay(10);

  Serial.print("Init SD card...");
  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("init failed!");
    return;
  }
  Serial.println("SD init ok");

  //aaAudio.I2S_PIN_LRCK = 28;  // Use different LRCK pin for Feather Express 52840
  aaAudio.maxBufferSize = AUDIO_BUFFER_SIZE;
  aaAudio.begin(0, 1, USE_I2S);

  playAudio(audioFilename);
}

void loop() {
  
  loadBuffer();

  // Control via Serial for testing
  if (Serial.available()) {
    char c = Serial.read();
    if (c == '=') {
      volumeControl += 0.1;
    } else if (c == '-') {
      volumeControl -= 0.1;
      volumeControl = max(0.0, volumeControl);
    } else if (c == 'p') {
      playAudio("waitress.mp3");
    }
    Serial.println(volumeControl);
  }

}


File myFile;

void playAudio(const char* audioFile) {

  if (myFile) {
    myFile.close();
    MP3.end();
  }
  //Open the designated file
  myFile = SD.open(audioFile);

  MP3.begin(myFile);
  MP3.getMetadata();
  aaAudio.setSampleRate(MP3.Fs, 1);
  Serial.println(MP3.Fs);
  aaAudio.dacBitsPerSample = MP3.bitsPerSample;
  Serial.println(MP3.bitsPerSample);
}

void loadBuffer() {

  if (myFile.available() > AUDIO_BUFFER_SIZE) {
    uint32_t sampleCounter = 0;
    for (uint32_t i = 0; i < 100; i++) {
      audio = MP3.decode();
      memcpy(&aaAudio.dacBuffer16[sampleCounter], audio.interleaved, 128);  // 128 bytes
      sampleCounter += 64;                                                  // 64 samples per go
    }
    for (uint32_t i = 0; i < 6400; i++) {
      int16_t sample = aaAudio.dacBuffer16[i];
      sample *= volumeControl;
      aaAudio.dacBuffer16[i] = sample;
    }
    aaAudio.feedDAC(0, 6400);
  } else {
    myFile.seek(0);
  }
}


Pinouts for test code & MAX98357A:
BCLK connected to Arduino D1 (p0.03)
LRCK connected to Arduino D3 (p0.29)
DIN connected to Arduino D5 (p0.05)
SD connected to Arduino D6
GAIN connected to VIN
SD Card:
SD Card CS Pin user selected