I2S DAC Mode
Posted: Wed Jun 19, 2024 6:21 pm
Hello I'm working on audio project. I used i2s_a2dp_sink example with DAC mode. But I got ringbuffer overflowed error on DAC output mode. Here is my I2S config and task handler codes below:
[Codebox]
dac_continuous_config_t cont_cfg =
{
.chan_mask = DAC_CHANNEL_MASK_ALL,
.desc_num = 8,
// .buf_size = 2048,
.buf_size = 4092,
.freq_hz = 44100,
.offset = 127,
// .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range
.clk_src = DAC_DIGI_CLK_SRC_APLL, // Using APLL as clock source to get a wider frequency range
// .chan_mode = DAC_CHANNEL_MODE_ALTER,
.chan_mode = DAC_CHANNEL_MODE_SIMUL,
};
/* Allocate continuous channels */
ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &tx_chan));
/* Enable the continuous channels */
ESP_ERROR_CHECK(dac_continuous_enable(tx_chan));
[/Codebox]
[Codebox]
static void bt_i2s_task_handler(void *arg)
{
uint8_t *data = NULL;
size_t item_size = 0;
/**
* The total length of DMA buffer of I2S is:
* `dma_frame_num * dma_desc_num * i2s_channel_num * i2s_data_bit_width / 8`.
* Transmit `dma_frame_num * dma_desc_num` bytes to DMA is trade-off.
*/
// const size_t item_size_upto = 240 * 6;
const size_t item_size_upto = 4092 * 8 * 2 * 16;
size_t bytes_written = 0;
for (;;)
{
if (pdTRUE == xSemaphoreTake(s_i2s_write_semaphore, portMAX_DELAY))
{
for (;;)
{
item_size = 0;
/* receive data from ringbuffer and write it to I2S DMA transmit buffer */
data = (uint8_t *)xRingbufferReceiveUpTo(s_ringbuf_i2s, &item_size, (TickType_t)pdMS_TO_TICKS(20), item_size_upto);
if (item_size == 0)
{
ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer underflowed! mode changed: RINGBUFFER_MODE_PREFETCHING");
ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING;
break;
}
// #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC
dac_continuous_write(tx_chan, data, item_size, &bytes_written, -1);
// #else
// i2s_channel_write(tx_chan, data, item_size, &bytes_written, portMAX_DELAY);
// #endif
vRingbufferReturnItem(s_ringbuf_i2s, (void *)data);
}
}
}
}
[/Codebox]
Here is output:
[Codebox]
W (12628) BT_APPL: new conn_srvc id:19, app_id:1
I (12638) BT_AV: ESP_BT_GAP_MODE_CHG_EVT mode: 0
I (12638) BT_AV: A2DP audio state: Started
I (12638) RC_CT: AVRC event notification: 1
I (12648) BT_AV: Playback status changed: 0x1
I (12768) BT_APP_CORE: ringbuffer data increased! mode changed: RINGBUFFER_MODE_PROCESSING
W (12838) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (12868) BT_APP_CORE: ringbuffer is full, drop this packet!
I (12868) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (12868) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (12878) BT_APP_CORE: ringbuffer is full, drop this packet!
I (12888) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (12898) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (12918) BT_APP_CORE: ringbuffer is full, drop this packet!
I (12918) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13118) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13128) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13128) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13138) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13158) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13158) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13178) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13188) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13188) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13198) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13218) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13218) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13238) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13248) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13248) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13258) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13278) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13288) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13288) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13298) BT_APP_CORE: ringbuffer is full, drop this packet!
[/Codebox]
Output audio sound like slowed and noisy. What should I do?
Thanks in advance.
[Codebox]
dac_continuous_config_t cont_cfg =
{
.chan_mask = DAC_CHANNEL_MASK_ALL,
.desc_num = 8,
// .buf_size = 2048,
.buf_size = 4092,
.freq_hz = 44100,
.offset = 127,
// .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range
.clk_src = DAC_DIGI_CLK_SRC_APLL, // Using APLL as clock source to get a wider frequency range
// .chan_mode = DAC_CHANNEL_MODE_ALTER,
.chan_mode = DAC_CHANNEL_MODE_SIMUL,
};
/* Allocate continuous channels */
ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &tx_chan));
/* Enable the continuous channels */
ESP_ERROR_CHECK(dac_continuous_enable(tx_chan));
[/Codebox]
[Codebox]
static void bt_i2s_task_handler(void *arg)
{
uint8_t *data = NULL;
size_t item_size = 0;
/**
* The total length of DMA buffer of I2S is:
* `dma_frame_num * dma_desc_num * i2s_channel_num * i2s_data_bit_width / 8`.
* Transmit `dma_frame_num * dma_desc_num` bytes to DMA is trade-off.
*/
// const size_t item_size_upto = 240 * 6;
const size_t item_size_upto = 4092 * 8 * 2 * 16;
size_t bytes_written = 0;
for (;;)
{
if (pdTRUE == xSemaphoreTake(s_i2s_write_semaphore, portMAX_DELAY))
{
for (;;)
{
item_size = 0;
/* receive data from ringbuffer and write it to I2S DMA transmit buffer */
data = (uint8_t *)xRingbufferReceiveUpTo(s_ringbuf_i2s, &item_size, (TickType_t)pdMS_TO_TICKS(20), item_size_upto);
if (item_size == 0)
{
ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer underflowed! mode changed: RINGBUFFER_MODE_PREFETCHING");
ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING;
break;
}
// #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC
dac_continuous_write(tx_chan, data, item_size, &bytes_written, -1);
// #else
// i2s_channel_write(tx_chan, data, item_size, &bytes_written, portMAX_DELAY);
// #endif
vRingbufferReturnItem(s_ringbuf_i2s, (void *)data);
}
}
}
}
[/Codebox]
Here is output:
[Codebox]
W (12628) BT_APPL: new conn_srvc id:19, app_id:1
I (12638) BT_AV: ESP_BT_GAP_MODE_CHG_EVT mode: 0
I (12638) BT_AV: A2DP audio state: Started
I (12638) RC_CT: AVRC event notification: 1
I (12648) BT_AV: Playback status changed: 0x1
I (12768) BT_APP_CORE: ringbuffer data increased! mode changed: RINGBUFFER_MODE_PROCESSING
W (12838) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (12868) BT_APP_CORE: ringbuffer is full, drop this packet!
I (12868) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (12868) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (12878) BT_APP_CORE: ringbuffer is full, drop this packet!
I (12888) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (12898) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (12918) BT_APP_CORE: ringbuffer is full, drop this packet!
I (12918) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13118) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13128) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13128) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13138) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13158) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13158) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13178) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13188) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13188) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13198) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13218) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13218) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13238) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13248) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13248) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13258) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13278) BT_APP_CORE: ringbuffer is full, drop this packet!
I (13288) BT_APP_CORE: ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING
W (13288) BT_APP_CORE: ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING
W (13298) BT_APP_CORE: ringbuffer is full, drop this packet!
[/Codebox]
Output audio sound like slowed and noisy. What should I do?
Thanks in advance.