Page 1 of 1

Clear / Silence TX I2S DMA Buffer

Posted: Wed Apr 23, 2025 9:01 am
by sentionic
After the audio output is stopped, the DMA buffer will still send output to the codec on repeat, unless the channel is disabled (or using auto clear). The trouble with using i2s_channel_disable(this->_txHandle) is that upon enabling the channel again, it will briefly repeat the previous sample, which causes a pop in the speaker.

I tried ramping, but was not successful. So I try filling the buffer with zeros but I cannot silence it. I would like more control over how to silence. What is silence? 0? The code that does not work is attached. Also attached is how I setup the channel. Please note that I would not like to use auto_clear

Code: Select all

const size_t dma_desc_num = 2;
const size_t dma_frame_num = 512;
const size_t bytes_per_sample = 2;
const size_t buffer_size = dma_frame_num * bytes_per_sample;

int16_t zero_buffer[dma_frame_num] = {0};
size_t bytes_written = 0;

for (int i = 0; i < dma_desc_num; i++) {
  i2s_channel_write(_txHandle, zero_buffer, buffer_size, &bytes_written, portMAX_DELAY);
}
i2s_channel_disable(this->_txHandle);

Code: Select all

i2s_chan_config_t chan_cfg = {};
chan_cfg.id = I2S_NUM_1;
chan_cfg.role = I2S_ROLE_MASTER;
chan_cfg.dma_desc_num = 2;
chan_cfg.dma_frame_num = 512;
chan_cfg.auto_clear = false;
chan_cfg.intr_priority = 1;
chan_cfg.allow_pd = false;
i2s_new_channel(&chan_cfg, &_txHandle, NULL);

_txConfiguration = new i2s_std_config_t();
_txConfiguration->gpio_cfg.bclk = (gpio_num_t)configuration.output.bitClock;
_txConfiguration->gpio_cfg.dout = (gpio_num_t)configuration.output.dataOut;
_txConfiguration->gpio_cfg.ws = (gpio_num_t)configuration.output.wordSelect;