Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors with MP3 playback #726

Open
Misterke opened this issue Jan 3, 2025 · 0 comments
Open

Errors with MP3 playback #726

Misterke opened this issue Jan 3, 2025 · 0 comments

Comments

@Misterke
Copy link
Contributor

Misterke commented Jan 3, 2025

I hoped that moving from an ESP8266 to an ESP32 (I tried both ESP32-C3 and now a WROOM) would solve all my problems, but ...

I reduced my platform.io program to:

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Arduino.h>
#include <EEPROM.h>
#include <I2S.h>
#include <LittleFS.h>
#include <SPI.h>
#include <WiFi.h>
#include <Wire.h>

#include "AudioFileSourceBuffer.h"
#include "AudioFileSourceICYStream.h"
#include "AudioFileSourceLittleFS.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"
#include "AudioOutputI2SNoDAC.h"

// Enter your WiFi setup here:
#define WIFI_HOSTNAME "XXXXXXXXXXXXXXXXXX"
#define WIFI_SSID "XXXXXXXXXXXXXXXXXX"
#define WIFI_PASSWORD "XXXXXXXXXXXXXXXXXX"

const char hostname[] = WIFI_HOSTNAME;
const char ssid[] = WIFI_SSID;
const char password[] = WIFI_PASSWORD;

Adafruit_SSD1306 display(128, 64, &Wire);

//  MetaData callback for handling information carried by the MP3 stream.
void metadataCB(void *cbData, const char *type, bool isUnicode, const char *string) {
  char s1[32], s2[64];
  strncpy_P(s1, type, sizeof(s1));
  s1[sizeof(s1) - 1] = 0;
  strncpy_P(s2, string, sizeof(s2));
  s2[sizeof(s2) - 1] = 0;
  Serial.printf("METADATA(%s) '%s' = '%s'\n", (const char *)cbData, s1, s2);
  Serial.flush();
}

void statusCB(void *cbData, int code, const char *string) {
  static bool lastWasSyncLoss = false;
  if(cbData && !strcmp((const char *)cbData, "MP3") && (code == 257)) {
    if(lastWasSyncLoss) return;
    lastWasSyncLoss = true;
  } else {
    lastWasSyncLoss = false;
  }

  char s1[64];
  strncpy_P(s1, string, sizeof(s1));
  s1[sizeof(s1) - 1] = 0;
  Serial.printf("STATUS(%s) '%d' = '%s'\n", (const char *)cbData, code, s1);
  Serial.flush();
}

void triangle(bool reset = false) {
  static int16_t step = 0;
  if(reset) step = 0;

  if(!step) display.clearDisplay();
  display.drawTriangle(display.width() / 2, display.height() / 2 - step, display.width() / 2 - step,
                       display.height() / 2 + step, display.width() / 2 + step, display.height() / 2 + step, WHITE);
  display.display();
  step += 5;
  if(2 * step >= min(display.width(), display.height())) step = 0;
}

void rectangle(bool reset = false) {
  static int16_t step = 0;
  if(reset) step = 0;

  if(!step) display.clearDisplay();
  display.drawRoundRect(display.width() / 2 - step, display.height() / 2 - step, 2 * step, 2 * step, step / 4, WHITE);
  display.display();
  step += 5;
  if(2 * step >= min(display.width(), display.height())) step = 0;
}

void connectToWIFI() {
  WiFi.disconnect();
  WiFi.softAPdisconnect(true);
  WiFi.mode(WIFI_STA);
  WiFi.hostname(hostname);
  WiFi.begin(ssid, password);

  // Try forever
  while(WiFi.status() != WL_CONNECTED) {
    rectangle();
    // triangle();
  }

  Serial.println(F("Connected"));
}

void setup() {
  Serial.begin(115200);
  delay(1000);

  Wire.setPins(GPIO_NUM_21, GPIO_NUM_22);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("Could not initialize SSD1306 display"));
  }
  display.clearDisplay();
  display.display();

  if(!LittleFS.begin()) {
    Serial.println(F("Could not initialize LittleFS"));
  }

  Serial.println(F("Connecting to WiFi"));
  connectToWIFI();

  fs::File root = LittleFS.open("/");
  bool first = true;
  if(root.isDirectory()) {
    root.rewindDirectory();
    for(;;) {
      boolean isDir = false;
      String name = root.getNextFileName(&isDir);
      if(name.length()) {
        if(isDir) {
          Serial.print(name);
          Serial.println('/');
        } else {
          Serial.println(name);
        }
      } else {
        break;
      }
    }
  }
  root.close();
  audioLogger = &Serial;
}

static AudioOutput *out = nullptr;
static AudioFileSource *src = nullptr;
static AudioFileSourceBuffer *buf = nullptr;
static AudioGenerator *gen = nullptr;

void destroyAudio() {
  if(gen) {
    gen->stop();
    delete gen;
    gen = nullptr;
  }
  if(buf) {
    buf->close();
    delete buf;
    buf = nullptr;
  }
  if(src) {
    src->close();
    delete src;
    src = nullptr;
  }
  if(out) {
    out->stop();
    delete out;
    out = nullptr;
  }
}

void playAudio() {
  if (out && src && buf && gen) {
    if (gen->isRunning() && gen->loop()) {
      triangle();
      return;
    } else {
      Serial.println(F("MP3 playback stopped"));
      destroyAudio();
    }
  } 

  if(!out) {
    // out = new AudioOutputI2S();
    //((AudioOutputI2S *)out)->SetPinout(GPIO_NUM_6,GPIO_NUM_8,GPIO_NUM_7);
    out = new AudioOutputI2SNoDAC();
  }
  if(out && !src) {
    // src = new AudioFileSourceICYStream("http://a1rj.streams.com.br:7801/sm");
    // src = new AudioFileSourceICYStream("http://streams.radio.dpgmedia.cloud/redirect/joe_fm/mp3");
    //((AudioFileSourceICYStream *)src)->SetReconnect(3, 10);
    src = new AudioFileSourceLittleFS("/phone.mp3");
    src->RegisterMetadataCB(metadataCB, (void *)"ICY");
    src->RegisterStatusCB(statusCB, (void *)"ICY");
  }
  if(out && src && !buf) {
    buf = new AudioFileSourceBuffer(src, 512);
    buf->RegisterMetadataCB(metadataCB, (void *)"BUF");
    buf->RegisterStatusCB(statusCB, (void *)"BUF");
  }
  if(out && src && buf && !gen) {
    gen = new AudioGeneratorMP3();
    gen->RegisterMetadataCB(metadataCB, (void *)"MP3");
    gen->RegisterStatusCB(statusCB, (void *)"MP3");
    if(gen->begin(buf, out)) {
      Serial.println(F("MP3 playback started"));
      triangle(true);
    } else {
      destroyAudio();
    }
  } 
}

void loop() {
  playAudio();
  if(WiFi.status() != WL_CONNECTED) {
    rectangle(true);
    destroyAudio();
    connectToWIFI();
  }
}

Basically just trying to play a short MP3 file of a phone ringing from LittleFS, which the code in setup() also shows being present when starting this on my ESP32 WROOM device. I'm not even at the point yet where the audio-quality interests me. Just getting the MP3 decoding to work without errors would be step 1 ...

Unfortunately even that doesn't work (whereas I have similar - but not exactly the same - code on ESP8266 which does work). Instead I get following output from the status callback for every playback of the file:

MP3 playback started
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(BUF) '3' = 'Buffer underflow'
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 2693'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 2719'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 2720'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 2721'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 2849'
STATUS(BUF) '3' = 'Buffer underflow'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 3576'
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 3578'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 4101'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 4102'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 4103'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 4109'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 4110'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 4546'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 4547'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 4548'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 4788'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 4921'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 4923'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 4927'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 4929'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 4933'
STATUS(MP3) '258' = 'Decoding error 'reserved header layer value' at byte offset 493'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 4935'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 4946'
STATUS(BUF) '3' = 'Buffer underflow'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 5760'
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 5762'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 6308'
STATUS(MP3) '565' = 'Decoding error 'bad main_data_begin pointer' at byte offset 687'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 8127'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 8129'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 8130'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 8131'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 8203'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 8218'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 8219'
STATUS(BUF) '3' = 'Buffer underflow'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 9084'
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 9086'
STATUS(BUF) '3' = 'Buffer underflow'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 10545'
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 10547'
STATUS(MP3) '513' = 'Decoding error 'CRC check failed' at byte offset 11099'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 11387'
STATUS(BUF) '3' = 'Buffer underflow'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 12114'
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 12116'
STATUS(MP3) '258' = 'Decoding error 'reserved header layer value' at byte offset 126'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 12700'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 12751'
STATUS(MP3) '565' = 'Decoding error 'bad main_data_begin pointer' at byte offset 128'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 13236'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 13328'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 13329'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 13330'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 13331'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 13575'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 13725'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 13726'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 13730'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 13732'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 13915'
STATUS(MP3) '565' = 'Decoding error 'bad main_data_begin pointer' at byte offset 139'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 14396'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 14879'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 14880'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 14881'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 15265'
STATUS(MP3) '258' = 'Decoding error 'reserved header layer value' at byte offset 152'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 15281'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 15299'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 15301'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 15479'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 15521'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 15522'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 15523'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 16007'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 16743'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 16745'
STATUS(MP3) '260' = 'Decoding error 'reserved sample frequency value' at byte offset'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 16748'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 16805'
STATUS(MP3) '258' = 'Decoding error 'reserved header layer value' at byte offset 168'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 16807'
STATUS(MP3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 16808'
STATUS(MP3) '257' = 'Decoding error 'lost synchronization' at byte offset 16809'
STATUS(MP3) '565' = 'Decoding error 'bad main_data_begin pointer' at byte offset 168'
STATUS(BUF) '3' = 'Buffer underflow'
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(BUF) '3' = 'Buffer underflow'
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(BUF) '3' = 'Buffer underflow'
STATUS(MP3) '1' = 'Decoding error 'input buffer too small (or EOF)' at byte offset'
MP3:ERROR_BUFLEN 0
STATUS(BUF) '2' = 'Refilling buffer'
STATUS(BUF) '3' = 'Buffer underflow'
MP3 playback stopped
UNINSTALL I2S

I checked the MP3 file and it's fine (here it is in a ZIP file: phone.zip). My ultimate goal is playing an MP3 Internet stream to an I2S DAC, but as that gave similar issues, I simplified the code to this LittleFS playback.

I did also try with an older (0.9.7) version and had the same issues there.
I did also try using an AudioOutputNull instead of AudioOutputI2S and AudioOutputI2SNoDAC, but to no avail.

So, I'm out of ideas ...
Any help or at least confirmation that this is a known problem would be very welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant