Skip to content

Commit 39872d3

Browse files
authored
feat(esp-box): Improve audio configuration and behavior (#551)
* feat(esp-box): Improve audio configuration * always write the full buffer
1 parent 188d261 commit 39872d3

File tree

2 files changed

+23
-60
lines changed

2 files changed

+23
-60
lines changed

components/esp-box/include/esp-box.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,11 +521,10 @@ class EspBox : public BaseComponent {
521521
std::unique_ptr<espp::Task> audio_task_{nullptr};
522522
// i2s / low-level audio
523523
i2s_chan_handle_t audio_tx_handle{nullptr};
524+
i2s_chan_handle_t audio_rx_handle{nullptr};
524525
std::vector<uint8_t> audio_tx_buffer;
525526
StreamBufferHandle_t audio_tx_stream;
526527
i2s_std_config_t audio_std_cfg;
527-
i2s_event_callbacks_t audio_tx_callbacks_;
528-
std::atomic<bool> has_sound{false};
529528

530529
// IMU
531530
std::shared_ptr<Imu> imu_;

components/esp-box/src/audio.cpp

Lines changed: 22 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@ using namespace espp;
66
// Audio Functions //
77
////////////////////////
88

9-
static TaskHandle_t play_audio_task_handle_ = NULL;
10-
11-
static bool IRAM_ATTR audio_tx_sent_callback(i2s_chan_handle_t handle, i2s_event_data_t *event,
12-
void *user_ctx) {
13-
// notify the main task that we're done
14-
vTaskNotifyGiveFromISR(play_audio_task_handle_, NULL);
15-
return true;
16-
}
17-
189
bool EspBox::initialize_codec() {
1910
logger_.info("initializing codec");
2011

@@ -27,15 +18,15 @@ bool EspBox::initialize_codec() {
2718
audio_hal_codec_config_t cfg;
2819
memset(&cfg, 0, sizeof(cfg));
2920
cfg.codec_mode = AUDIO_HAL_CODEC_MODE_DECODE;
30-
cfg.dac_output = AUDIO_HAL_DAC_OUTPUT_LINE1;
21+
cfg.dac_output = AUDIO_HAL_DAC_OUTPUT_ALL; // Enable both L and R outputs
3122
cfg.i2s_iface.bits = AUDIO_HAL_BIT_LENGTH_16BITS;
3223
cfg.i2s_iface.fmt = AUDIO_HAL_I2S_NORMAL;
3324
cfg.i2s_iface.mode = AUDIO_HAL_MODE_SLAVE;
34-
cfg.i2s_iface.samples = AUDIO_HAL_16K_SAMPLES;
25+
cfg.i2s_iface.samples = AUDIO_HAL_48K_SAMPLES;
3526

3627
ret_val |= es8311_codec_init(&cfg);
37-
ret_val |= es8311_set_bits_per_sample(cfg.i2s_iface.bits);
38-
ret_val |= es8311_config_fmt((es_i2s_fmt_t)cfg.i2s_iface.fmt);
28+
ret_val |= es8311_config_fmt(ES_I2S_NORMAL);
29+
ret_val |= es8311_set_bits_per_sample(AUDIO_HAL_BIT_LENGTH_16BITS);
3930
ret_val |= es8311_codec_set_voice_volume(volume_);
4031
ret_val |= es8311_codec_ctrl_state(cfg.codec_mode, AUDIO_HAL_CTRL_START);
4132

@@ -51,45 +42,25 @@ bool EspBox::initialize_codec() {
5142
bool EspBox::initialize_i2s(uint32_t default_audio_rate) {
5243
logger_.info("initializing i2s driver");
5344
logger_.debug("Using newer I2S standard");
54-
i2s_chan_config_t chan_cfg = {
55-
.id = i2s_port,
56-
.role = I2S_ROLE_MASTER,
57-
.dma_desc_num = 16, // TODO: calculate form audio rate
58-
.dma_frame_num = 48, // TODO: calculate from audio rate
59-
.auto_clear = true,
60-
.auto_clear_before_cb = false,
61-
.allow_pd = false,
62-
.intr_priority = 0,
63-
};
6445

65-
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &audio_tx_handle, nullptr));
46+
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(i2s_port, I2S_ROLE_MASTER);
47+
chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA buffer
48+
// chan_cfg.dma_desc_num = 16;
49+
// chan_cfg.dma_frame_num = 48;
50+
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &audio_tx_handle, &audio_rx_handle));
6651

6752
audio_std_cfg = {
68-
.clk_cfg =
69-
{
70-
.sample_rate_hz = default_audio_rate,
71-
.clk_src = I2S_CLK_SRC_DEFAULT,
72-
.ext_clk_freq_hz = 0,
73-
.mclk_multiple = I2S_MCLK_MULTIPLE_256,
74-
},
53+
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(default_audio_rate),
7554
.slot_cfg =
7655
I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
77-
.gpio_cfg =
78-
{
79-
.mclk = i2s_mck_io,
80-
.bclk = i2s_bck_io,
81-
.ws = i2s_ws_io,
82-
.dout = i2s_do_io,
83-
.din = i2s_di_io,
84-
.invert_flags =
85-
{
86-
.mclk_inv = false,
87-
.bclk_inv = false,
88-
.ws_inv = false,
89-
},
90-
},
56+
.gpio_cfg = {.mclk = i2s_mck_io,
57+
.bclk = i2s_bck_io,
58+
.ws = i2s_ws_io,
59+
.dout = i2s_do_io,
60+
.din = i2s_di_io,
61+
.invert_flags = {.mclk_inv = false, .bclk_inv = false, .ws_inv = false}},
9162
};
92-
audio_std_cfg.clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_256;
63+
// audio_std_cfg.clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_256;
9364

9465
ESP_ERROR_CHECK(i2s_channel_init_std_mode(audio_tx_handle, &audio_std_cfg));
9566

@@ -98,12 +69,6 @@ bool EspBox::initialize_i2s(uint32_t default_audio_rate) {
9869

9970
audio_tx_stream = xStreamBufferCreate(buffer_size * 4, 0);
10071

101-
play_audio_task_handle_ = xTaskGetCurrentTaskHandle();
102-
103-
memset(&audio_tx_callbacks_, 0, sizeof(audio_tx_callbacks_));
104-
audio_tx_callbacks_.on_sent = audio_tx_sent_callback;
105-
i2s_channel_register_event_callback(audio_tx_handle, &audio_tx_callbacks_, NULL);
106-
10772
xStreamBufferReset(audio_tx_stream);
10873

10974
ESP_ERROR_CHECK(i2s_channel_enable(audio_tx_handle));
@@ -155,7 +120,7 @@ bool EspBox::audio_task_callback(std::mutex &m, std::condition_variable &cv, boo
155120
i2s_channel_write(audio_tx_handle, buffer, buffer_size, NULL, portMAX_DELAY);
156121
} else {
157122
xStreamBufferReceive(audio_tx_stream, buffer, available, 0);
158-
i2s_channel_write(audio_tx_handle, buffer, available, NULL, portMAX_DELAY);
123+
i2s_channel_write(audio_tx_handle, buffer, buffer_size, NULL, portMAX_DELAY);
159124
}
160125
return false; // don't stop the task
161126
}
@@ -194,6 +159,10 @@ void EspBox::audio_sample_rate(uint32_t sample_rate) {
194159
// stop the channel
195160
i2s_channel_disable(audio_tx_handle);
196161
// update the sample rate
162+
auto err = es8311_codec_set_sample_rate(sample_rate);
163+
if (err != ESP_OK) {
164+
logger_.error("Could not set codec sample rate: {}", err);
165+
}
197166
audio_std_cfg.clk_cfg.sample_rate_hz = sample_rate;
198167
i2s_channel_reconfig_std_clock(audio_tx_handle, &audio_std_cfg.clk_cfg);
199168
// clear the buffer
@@ -205,11 +174,6 @@ void EspBox::audio_sample_rate(uint32_t sample_rate) {
205174
void EspBox::play_audio(const std::vector<uint8_t> &data) { play_audio(data.data(), data.size()); }
206175

207176
void EspBox::play_audio(const uint8_t *data, uint32_t num_bytes) {
208-
play_audio_task_handle_ = xTaskGetCurrentTaskHandle();
209-
if (has_sound) {
210-
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
211-
}
212177
// don't block here
213178
xStreamBufferSendFromISR(audio_tx_stream, data, num_bytes, NULL);
214-
has_sound = true;
215179
}

0 commit comments

Comments
 (0)