ESP32-audioI2S icon indicating copy to clipboard operation
ESP32-audioI2S copied to clipboard

ESP32 without PSRAM crashing after playing (SD) or silent (on 2nd streaming)

Open kaloprojects opened this issue 5 months ago • 31 comments

Hi @schreibfaul1 Wolle,

i found two issues in your current AUDIO.H, maybe a tiny detail/bug in code but with huge impact ;). Writing both here as they seem to be related (appear on non-PSRAM only). Background: I found it more by accident on my ESP32 Chat project when I tested my current code .. after weeks again with non-PSRAM ESP32. So it could be that the 'bug' exists maybe longer ago, not caused from any updates you did days or weeks ago (i don't know).

Fortunately I can reproduce the problems also on your demo sketch, this makes it much easier for you to reproduce yourself :blush: In Summary: 2 issues detected,:

Issue 1: ‘CRASH & reboot on connecttoFS() – appears on ESP32 without PSRAM (or alternatively on ESP with PSRAM but PSRAM disabled):

this code line plays audio from SD successfully audio.connecttoFS(SD, "/welcome.wav"); but when finished then the ESP crashes ALWAYS immediately with exactly this line after audio succesfully played in speaker:

info        Closing audio file "welcome.wav"
CORRUPT HEAP: Bad head at 0x3ffefac4. Expected 0xabba1234 got 0x00000000
assert failed: multi_heap_free multi_heap_poisoning.c:279 (head != NULL)

Backtrace: 0x400828c4:0x3ffb1ee0 0x … then rebooting itself

Issue 2: ‘ANY 2nd Audio no longer playing’ – also with ESP32 without PSRAM (or ESP with PSRAM but disabled):

// e.g. playing a Google audio event 1
audio.connecttospeech("Wenn die Hunde schlafen ist alles gut.", "de"); // Google TTS
while (audio.isRunning()) { audio.loop(); vTaskDelay(1); }  // waiting until done

// then playing a new event, e.g. Google again or Open AI, or radio streaming .. Result: no Audio any longer
audio.connecttohost("http://stream.antennethueringen.de/live/aac-64/stream.antennethueringen.de/"); // aac
while (audio.isRunning()) { audio.loop(); vTaskDelay(1); }  // forever   

The 2nd audio is never played, the info progess, looking good until last last, then ending with:

...
info        The AACDecoder could not be initialized

It doesn’t matter which audio type you play first (Google/OpenAI/Readio) .. the 2nd one will never be played, no Crash, but speaker silent

IMPORTANT: All works well with ESP with PSRAM (e.g. ESP32 Wrover DevKit), both issue do not appear if PSRAM exist and enabled.

I tested all with multiple AUDIO.H versions (including your latest ESP32-audioI2S-3.2.0g, also the 3.2.0 and earlier versions), also using latest arduino-esp32 library (3.2.0, based on ESP-IDF v5.4.1)

Long story sort: in summary it looks to me that maybe any detail in audio.cpp is adressing PSRAM memory even in case no PSRAM exist ? ... a/o running out of heap after audio event played succesfully ?.

Please let me know if you need any more details (or .log prints)!, I am very happy to follow up on any testing on my side to support you as best i can! .

Thank you @schreibfaul1 in prepare!!, 👍 hope it helps & it is not too much work in bug fixing :blush: (in case i missed anything or coded wrong let me know)

_

Below the code I am using, allowing you to reproduce This happens:

  • ESP32 with PSRAM play all 4 event perfectly, one by one.
  • Non-PSRAM ESP32 crashing after Audio 1 reached end -> Rebooting. If removing audio event 1 (SD) then Google TTS plays once, no CRASH .. all audio after Google are 'silent' because 'decoder not found')
#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"
#include "SD.h"
#include "FS.h"

// Digital I/O used
#define SD_CS          5    
#define SPI_MOSI      23
#define SPI_MISO      19
#define SPI_SCK       18

#define I2S_DOUT      25    
#define I2S_BCLK      27
#define I2S_LRC       26

Audio audio;

String ssid =       "...";     
String password =   "...";
String OPENAI_KEY = "..."; 


void setup() {
    pinMode(SD_CS, OUTPUT);  digitalWrite(SD_CS, HIGH);
    SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
    Serial.begin(115200);
    SD.begin(SD_CS);
    WiFi.disconnect();
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid.c_str(), password.c_str());
    while (WiFi.status() != WL_CONNECTED) delay(1500);
    
    audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
    audio.setVolume(5); // default 0...21    
   
    // *** AUDIO Event 1 - local files ***  
    Serial.println ("***** SD starting now ... *****");
    audio.connecttoFS(SD, "/welcome.wav");     // SD
    while (audio.isRunning()) { audio.loop(); vTaskDelay(1); }  // waiting until done 
   
    // *** AUDIO Event 2 - Google TTS ***   
    Serial.println ("***** Google TTS starting now ... *****");
    audio.connecttospeech("Wenn die Hunde schlafen ist alles gut.", "de"); // Google TTS
    while (audio.isRunning()) { audio.loop(); vTaskDelay(1); }  // waiting until done
  
    // *** AUDIO Event 3 -  Open AI TTS ***    (just remove this event in case you don't have an API_KEY)
    // (details: 4th parameter/voice_instruct new since AUDIO.H v.3.1.0u)
    Serial.println ("***** Open AI starting now ... *****");
    audio.openai_speech(OPENAI_KEY, "tts-1", "Hallo, wie gehts ?", "", "onyx", "aac", "1");   
    while (audio.isRunning()) { audio.loop(); vTaskDelay(1); }  // waiting until done 
     
    // *** AUDIO Event 4 -  Radio streams ***  
    Serial.println ("***** Streaming starting now ... *****");
    audio.connecttohost("http://stream.antennethueringen.de/live/aac-64/stream.antennethueringen.de/"); // aac
    while (audio.isRunning()) { audio.loop(); vTaskDelay(1); }  // forever        
}


void loop(){    
    audio.loop(); 
    vTaskDelay(1); 
}

Complete Output:

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4888
load:0x40078000,len:16516
load:0x40080400,len:4
load:0x40080404,len:3476
entry 0x400805b4
info        audioI2S Version 3.2.0g
***** SD starting now ... *****
info        PSRAM not found, inputBufferSize: 13951 bytes
info        buffers freed, free Heap: 109416 bytes
info        Reading file: "/welcome.wav"
info        FormatCode: 1
info        DataRate: 96000
info        DataBlockSize: 4
info        BitsPerSample: 16
info        Audio-Length: 258516
info        stream ready
info        syncword found at pos 0
info        Channels: 2
info        SampleRate: 24000
info        BitsPerSample: 16
info        BitRate: 768000
info        Closing audio file "welcome.wav"
CORRUPT HEAP: Bad head at 0x3ffefac4. Expected 0xabba1234 got 0x00000000

assert failed: multi_heap_free multi_heap_poisoning.c:279 (head != NULL)

Backtrace: 0x400828bc:0x3ffb1ef0 0x4008dee1:0x3ffb1f10 0x40094085:0x3ffb1f30 0x40092d8b:0x3ffb2070 0x40083bcb:0x3ffb2090 0x400940cd:0x3ffb20b0 0x4008968b:0x3ffb20d0 0x400896ef:0x3ffb20f0 0x40102026:0x3ffb2110 0x40101e95:0x3ffb2130 0x400d7940:0x3ffb2160 0x400e01be:0x3ffb2190 0x400e438d:0x3ffb21b0 0x400d2de7:0x3ffb21d0 0x40105fcf:0x3ffb2270 0x4008eb36:0x3ffb2290

ELF file SHA256: d525551c2
Rebooting...

Settings of my ESP32 Wroom NodeMU Devkit (no PSRAM):

Image

kaloprojects avatar May 23 '25 18:05 kaloprojects