ESP32 Memory Management

Hi. This is more of a compiling question than a programming one but here goes. I have a program that about 1100 lines of code and right up until I added the last part, it all worked just fine. The last part added was the ability to play a small audio clip through I2s. I am using Phil Schatzmann's excellent tools.

When I added the libraries to play the clip except for the clip itself, it compiled fine. Here is the result of the compile...

Compiling 'YMCrossing_ESP32' for 'ESP32 Dev Module(esp32_esp32)'
 
Program size: 1320101 bytes (used 39% of a 3342336 byte maximum) (54.19 secs)
Minimum Memory Usage: 50564 bytes (15% of a 327680 byte maximum)

The sound clip is a 473KB mp3 encoded .h file that is brough into memory at compile time. When I compile, I get the following error...

Compiling 'YMCrossing_ESP32' for 'ESP32 Dev Module(esp32_esp32)'
ld.exe: C:\\Users\\xxxxxxx\\AppData\\Local\\Temp\\VMBuilds\\YMCrossing_ESP32\\esp32_esp32\\Debug\YMCrossing_ESP32.ino.elf section .dram0.bss will not fit in region dram0_0_seg

Error linking for board ESP32 Dev Module(esp32_esp32)
Build failed for project 'YMCrossing_ESP32'
ld.exe: DRAM segment data does not fit
ld.exe: DRAM segment data does not fit
ld.exe: region dram0_0_seg overflowed by 4312 bytes
 
collect2.exe*: error: ld returned 1 exit status

I am not new to ESP32 programming but I have never had to worry about memory management before. Everything just fit and worked. Even so, knowing that I would need to load a file in, I have been careful about variable and constant sizes, etc.

The device is an ESP32. (The final version will use an ESP32-S3.) It is a 8MB version. The partition selection is "8MB w/SPIFFS (3MB APP, 1.5MB SPIFFS). Just seems to me that there should be plenty of room for all of this.

I really don't want to add an SD card just for this.

Any help is greatly appreciated.

You are plenty of room regarding the FLASH memory, but the error is related to the DRAM memory (Data RAM) which is approximately 500kb, of which approximately half is occupied by the ESP32 core itself.

Instead of copying the file into the micro's DRAM, you should play the mp3 directly from the flash memory.

Try to post at least the instructions you use for the mp3 file part.

Hey, thanks for the reply. Exactly what I thought. Should be plenty of room. Getting back to my point about not knowing much about managing memory, I don't know how to determine where the file goes.

One thing I forgot to mention. I wrote a small program to test out just the playing of the audio. The program needs to repeat the clip several times. When I used an encoded mp3, there was a very noticeable delay each time the clip was replayed. When I went to a wav file, that delay was either gone or not noticeable. So it is a wave file I am playing. (wavBell.h)

Here is the part of the code where the libraries are added as well as the sound clip along with creating the object...

#include <Bounce2.h>
#include <BLEServer.h>
#include <BLEDevice.h>
#include <BLE2902.h>
#include <BLEUtils.h>
#include "AudioTools.h"
#include "wavBell.h"

//	Instantiate the Bell Sound
MemoryStream Bell(wavBell_wav, wavBell_wav_len);
I2SStream i2s;
EncodedAudioStream out(&i2s, new WAVDecoder()); // output to decoder
StreamCopy copier(out, Bell);    // copy in to i2s

Here is the part of the setup related to the sound....

	// Setup I2S Bell Sound
	auto cfg = i2s.defaultConfig();
	cfg.sample_rate = 24000;
	cfg.channels = 1;
	cfg.pin_data = 25;
	cfg.pin_bck = 32;
	cfg.pin_ws = 33;
	Bell.setLoop(true);
	i2s.begin(cfg);
	out.begin();

To actually play the sound, this goes into the loop section...

	//	Bell Sound
	copier.copy();
	if (Crossing.BellIsOn) {
		copier.copy();
		Bell.setLoop(true);
		}
	else {
		Bell.setLoop(false);
	}

Hope that helps.

Not only is 473KB pushing the limit of available RAM in the ESP32, but is definitely beyond the limit of maximum available contiguous RAM. I had a similar issue. My workaround was to use PSRAM. See: https://github.com/espressif/arduino-esp32/issues/8898

I suppose it is due to the fact that a WAV file is uncompressed and therefore does not require decoding: the PCM audio stream can be "forwarded" as is to the I2S device.

OK. Problem solved, at least for now.

My board selection was for the ESP32 Dev board. That is a 4MB device. I am not using a Dev board. I am using an ESP32-WROOM-32E. This has 8MB. I changed to that setting which is supposed to then create Ap0 and Ap1 space of 3M each and SPIFFs space of 1.5M. That created enough room. Just to create even more room, I shortened the wav file to just two bell rings that repeat instead of the six bell rings I had before.

The result was....

Compiling 'YMCrossing_ESP32' for 'ESP32 Dev Module(esp32_esp32)'
 
Program size: 1424273 bytes (used 43% of a 3342336 byte maximum) (59.80 secs)
Minimum Memory Usage: 84964 bytes (26% of a 327680 byte maximum)
 

That works for now. I think my next move is to look into using the SPIFFs space. I presume I can just add that sound clip there and read it into RAM when needed.

You can use this tool (currently only with the old IDE 1.x) to load a file into the flash based spiffs files system: Install ESP32 Filesystem Uploader in Arduino IDE | Random Nerd Tutorials.
You should be able to stream a wav file directly to the player from there so only a few buffer loads of it are in RAM at any one time.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.