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