earlephilhower / ESP8266Audio

Arduino library to play MOD, WAV, FLAC, MIDI, RTTTL, MP3, and AAC files on I2S DACs or with a software emulated delta-sigma DAC on the ESP8266 and ESP32
GNU General Public License v3.0
2.02k stars 432 forks source link

Data Out drops out periodically with ESP32 #635

Closed parabuzzle closed 1 year ago

parabuzzle commented 1 year ago

Hello,

I'm using an ESP32-WROVER-E-N16R8 but I've reproduced this on multiple E and IE series WROVER devices connected to a PCM5102a (I've used multiple modules to make sure it wasn't something related to the module either)

I noticed that the audio skips for a second randomly like there's a clock sync issue or something. This happens for WAV and MP3 files.

Any idea on why this dropout is happening? I have a hunch its the data reading from SPIFFS not loading a buffer fast enough on initial start up but I haven't been able to prove that.

Here's my Arduino sketch:

#include <Arduino.h>
#include <SPIFFS.h>
#include <I2S.h>
#include "AudioFileSourceSPIFFS.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"

#define I2S_DIN 26
#define I2S_LRCK 25
#define I2S_BCLK 14

AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
AudioOutputI2S *out;

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

  I2S.setDataPin(I2S_DIN);
  I2S.setFsPin(I2S_LRCK);
  I2S.setSckPin(I2S_BCLK);
  I2S.setBufferSize(512);

  log_i("Hello world");
  delay(1000);

  if (!SPIFFS.begin(true))
  {
    log_e("SPIFFS Mount Failed");
    while (1)
    {
      delay(1);
    }
    return;
  }

  log_i("SPIFFS Mount Success");

  file = new AudioFileSourceSPIFFS("/aur.mp3");
  mp3 = new AudioGeneratorMP3();
  out = new AudioOutputI2S();
  out->SetPinout(I2S_BCLK, I2S_LRCK, I2S_DIN);
  delay(1000);
  mp3->begin(file, out);
}

void loop()
{
  if (mp3->isRunning())
  {
    if (!mp3->loop())
      mp3->stop();
    log_i("Running");
  }
  else
  {
    mp3->stop();
    file->close();
    ESP.restart();
  }
}

The pins don't seem to make a difference. I've moved them around and even used the default pins for the library. The skip is still there.

I can see the skip on the scope:

channel 1: word clock (yellow) channel 2: data (blue) channel 3: bit clock (purple)

i2s_skip

This one shows that the skip duration is 64ms i2s_skip_64ms

The zoomed in signal (the probes are connected directly to the MCU pins. i2s_signal

zoomed in on the start of the dropout i2s_drop_start

zoomed in on the end of the dropout i2s_drop_end

earlephilhower commented 1 year ago

SPIFFS is horribly slow for both reads and writes (but it does have other benefits for flash usage and longevity with small updates, so horses for courses). You are showing an I2S underflow, meaning the app isn't sending decompressed data to the I2S device fast enough.

I suggest trying LittleFS instead as it's several X faster in my own experience than SPIFFS. You might also try adjusting the buffer size (up or down), but that may be specific file-dependent and not a general solution.

parabuzzle commented 1 year ago

Thank you.

For those that stumble upon this issue I just want to close the loop.

The problem was actually the SPIFFS speed. I switched to reading the data from an SD card and it worked without issue. LittleFS also seemed to still have the issue but it wasn't as often or consistent.

So bottom line is, SPIFFS is not really fast enough to service higher bitrate audio files.