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
1.98k stars 432 forks source link

Audio plays at half speed half pitch on M5 Stack Core2 #684

Closed wsanders closed 1 month ago

wsanders commented 1 month ago

I'm trying to get this library to work on an M5Stack Core2. All the examples I have been able to produce audio play back at half speed, half pitch. I suspect something is wrong with the I2S driver or the way it sets up the signals on The Core2. The Core2 is a ESP-32 D0WDQ3-V3 running at 240 MHz. The audio chip is NS4168, which seems to be a bog-standard I2S audio amp.

This issue seems to be insensitive to changes in sample rate, bit depth, mono/stereo mode, etc., as well as forcing APLL off in AudioOutputI2S.cpp. LIbrary version in 0.9.7 as installed via the Arduino IDE Library Manager.

Has anyone been able to get this library to work on a M5Stack Core2?

I've posted some examples at https://github.com/wsanders/M5Core2-Audio-Is-Broken. PlayMODFromPROGMEMToDAC.ino is only slightly modified from the ESP8266Audio examples and is probably easiest to get working since it plays a file from PROGMEM.

wsanders commented 1 month ago

This turned out to be an evil interaction with the Speaker.cpp code in the M5Core2 library, which stomps on the I2S setup. Disabling the speaker in the M5Core2 lib begin class fixes it - sort of. The headers are also important; although it works at half speed without including driver/i2s.h, that file must be included in a working version.

Yesterday, this sketch worked: in https://github.com/wsanders/M5Core2-Audio-Is-Broken: WSWebRadio-broken.ino. However, it was hard coded to play a low-bandwith stream I like. Today, it produces no audio. None of the sketches in that repo work.

Yesterday, when it worked playing my low-bandwith stream, it would also attempt to play a 192k stream but yielded broken audio and eventually barfed playing a 192k stream with lots of errors like:

STATUS(mp3) '259' = 'Decoding error 'forbidden bitrate value' at byte offset 75909' STATUS(mp3) '257' = 'Decoding error 'lost synchronization' at byte offset 76197'

Diddling with the MP3 buffer size doesn't seem to do anything. Could be some kind of uncaught buffer overrun: The touch screen of the Core2 stops working when the 192k stream plays, so it seems like an uncaught buffer overflow.

wsanders commented 1 month ago

After much trial and error I got the sketches to work, I posted working versions in https://github.com/wsanders/M5Core2-Audio-Is-Broken. The changes from some of the old existing code out there that does not work anymore:

After WiFi connects, the delay must be increased to at least 1 sec:

  while ( !WiFi.isConnected() ) delay(100);
  delay(1000);

Preallocating the source buffer seems to be essential:

const int preallocateBufferSize = 128*1024;
const int preallocateCodecSize = 85332; // AAC+SBR codec max mem needed
void *preallocateBuffer = NULL;
void *preallocateCodec = NULL;

  // Don't forget to malloc the buffers
  preallocateBuffer = malloc(preallocateBufferSize);
  preallocateCodec = malloc(preallocateCodecSize);
...
srcbuf = new AudioFileSourceBuffer(file, preallocateBuffer, preallocateBufferSize);
...
  // Preallocating the MP3 generator doesn't seem to be essential
  //gen = new AudioGeneratorMP3(preallocateCodec, preallocateCodecSize);

You must call M5.begin with the 6th argument false to disable the M5.Speaker code. Without this argument, the skeptch will produce audio, but at half speed and half pitch:

  M5.begin(true, false, true, true, kMBusModeOutput, false);

My M5Core2 library version is 0.1.9. I have 2.0.9 of the M5 board. definitions. I'll close this issue since the workarounds are related more to the M5 libraries than ESP32.