Page 1 of 1

I2S Buffer Size Question

Posted: Sun Dec 28, 2025 10:25 pm
by railfan
I am seeing some inconsistency between what I expect from the I2S buffer size and how the part is behaving.

Device: ESP32S2
arduino-esp32 v3.3.5 (IDF 5.5.1+)

I configure the dma_frame_num and dma_desc_num according to the defaults:

Code: Select all

        i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
        chan_cfg.dma_frame_num = 240;
        chan_cfg.dma_desc_num = 6;
        i2s_new_channel(&chan_cfg, &i2s_tx_handle, NULL);
I also read back the dma buffer size and get the 5760 bytes expected:

Code: Select all

        i2s_channel_get_info(i2s_tx_handle, &chan_info);
        dmaBufferSize = chan_info.total_dma_buf_size;
        Serial.print("DMA buffer size: ");
        Serial.println(dmaBufferSize);
Serial output:

Code: Select all

DMA buffer size: 5760
The 5760 value comes from:

dma_frame_num * dma_desc_num * (2 samples for stereo) * (2 bytes per sample)
= 240 * 6 * 2 * 2 = 5760

So, the setup of the I2S driver seems correct.

The i2s_channel_write function sends one sample (4 bytes) at a time (stereo, 16 bits each = 32 bits = 4 bytes) and has a 1ms timeout. It is also wrapped by a pin toggle to observe it on the scope:

Code: Select all

gpio_set_level(AUX3, 1);
                                i2s_channel_write(i2s_handle, &outputValue, 4, &bytesWritten, 1);
gpio_set_level(AUX3, 0);
When playing back the audio (which works fine), I only see 720 write calls (based on counting the pin toggles on the scope) before the timeout occurs, observed by the AUX3 pin (CH4 on the attached scope shot) sticking high for 1ms. However, I expected 1440 calls before the timeout (5760 / 4 bytes).

At first I thought there must be a factor of 2 I'm missing. However, if I increase dma_desc_num to 10 and run it again, I get:

Code: Select all

DMA buffer size: 9600
That's correct. But again, on the scope, it only loads 720 samples before hitting the i2s_channel_write timeout.

So, it seems like the effective dma_desc_num is somehow being limited to a value of 3 (720 / 240 = 3).

Oddly, if I set dma_desc_num to 3, it behaves like there is only a single 240 byte buffer (and the audio playback starts to have issues due to lack of adequate buffering).

Is my understanding of dma_desc_num flawed? Or is there some limit I'm bumping up against that isn't obvious and is capping the maximum number of buffers at 3 regardless of how many are requested?

Thanks,
Michael