I2S Buffer Size Question
Posted: Sun Dec 28, 2025 10:25 pm
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:
I also read back the dma buffer size and get the 5760 bytes expected:
Serial output:
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:
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:
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
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);
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);Code: Select all
DMA buffer size: 5760dma_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);
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: 9600So, 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