feat(examples): Add kconfig option for a2dp_sink example to use new audio APIs

This commit is contained in:
linruihao
2025-03-14 17:13:55 +08:00
parent 3da17f356c
commit d11be52064
5 changed files with 79 additions and 17 deletions

View File

@@ -61,4 +61,11 @@ menu "A2DP Example Configuration"
help
This enables the AVRCP Cover Art feature in example and try to get cover art image from peer device.
config EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC
bool "Use External Codec Instead of Internal"
default n
select BT_A2DP_USE_EXTERNAL_CODEC
help
If enable, Bluedroid stack will not decode A2DP audio data, user need to decode it in application layer.
endmenu

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -321,21 +321,21 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param)
/* when audio codec is configured, this event comes */
case ESP_A2D_AUDIO_CFG_EVT: {
a2d = (esp_a2d_cb_param_t *)(p_param);
ESP_LOGI(BT_AV_TAG, "A2DP audio stream configuration, codec type: %d", a2d->audio_cfg.mcc.type);
esp_a2d_mcc_t *p_mcc = &a2d->audio_cfg.mcc;
ESP_LOGI(BT_AV_TAG, "A2DP audio stream configuration, codec type: %d", p_mcc->type);
/* for now only SBC stream is supported */
if (a2d->audio_cfg.mcc.type == ESP_A2D_MCT_SBC) {
if (p_mcc->type == ESP_A2D_MCT_SBC) {
int sample_rate = 16000;
int ch_count = 2;
char oct0 = a2d->audio_cfg.mcc.cie.sbc[0];
if (oct0 & (0x01 << 6)) {
if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_32K) {
sample_rate = 32000;
} else if (oct0 & (0x01 << 5)) {
} else if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_44K) {
sample_rate = 44100;
} else if (oct0 & (0x01 << 4)) {
} else if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_48K) {
sample_rate = 48000;
}
if (oct0 & (0x01 << 3)) {
if (p_mcc->cie.sbc_info.ch_mode & ESP_A2D_SBC_CIE_CH_MODE_MONO) {
ch_count = 1;
}
#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC
@@ -362,11 +362,14 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param)
i2s_channel_reconfig_std_slot(tx_chan, &slot_cfg);
i2s_channel_enable(tx_chan);
#endif
ESP_LOGI(BT_AV_TAG, "Configure audio player: %x-%x-%x-%x",
a2d->audio_cfg.mcc.cie.sbc[0],
a2d->audio_cfg.mcc.cie.sbc[1],
a2d->audio_cfg.mcc.cie.sbc[2],
a2d->audio_cfg.mcc.cie.sbc[3]);
ESP_LOGI(BT_AV_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-%d-%d",
p_mcc->cie.sbc_info.samp_freq,
p_mcc->cie.sbc_info.ch_mode,
p_mcc->cie.sbc_info.block_len,
p_mcc->cie.sbc_info.num_subbands,
p_mcc->cie.sbc_info.alloc_mthd,
p_mcc->cie.sbc_info.min_bitpool,
p_mcc->cie.sbc_info.max_bitpool);
ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate: %d", sample_rate);
}
break;
@@ -381,6 +384,17 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param)
}
break;
}
/* when using external codec, after sep registration done, this event comes */
case ESP_A2D_SEP_REG_STATE_EVT: {
a2d = (esp_a2d_cb_param_t *)(p_param);
if (a2d->a2d_sep_reg_stat.reg_state == ESP_A2D_SEP_REG_SUCCESS) {
ESP_LOGI(BT_AV_TAG, "A2DP register SEP success, seid: %d", a2d->a2d_sep_reg_stat.seid);
}
else {
ESP_LOGI(BT_AV_TAG, "A2DP register SEP fail, seid: %d, state: %d", a2d->a2d_sep_reg_stat.seid, a2d->a2d_sep_reg_stat.reg_state);
}
break;
}
/* When protocol service capabilities configured, this event comes */
case ESP_A2D_SNK_PSC_CFG_EVT: {
a2d = (esp_a2d_cb_param_t *)(p_param);
@@ -591,6 +605,7 @@ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
case ESP_A2D_AUDIO_STATE_EVT:
case ESP_A2D_AUDIO_CFG_EVT:
case ESP_A2D_PROF_STATE_EVT:
case ESP_A2D_SEP_REG_STATE_EVT:
case ESP_A2D_SNK_PSC_CFG_EVT:
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
@@ -603,6 +618,8 @@ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
}
}
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE
void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
{
write_ringbuf(data, len);
@@ -613,6 +630,21 @@ void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
}
}
#else
void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf)
{
ESP_LOGI(BT_AV_TAG, "data_len: %d, number_frame: %d, ts: %lu", audio_buf->data_len, audio_buf->number_frame, audio_buf->timestamp);
/*
* Normally, user should send the audio_buf to other task, decode and free audio buff,
* But the codec component is not merge into IDF now, so we just free audio data here
*/
esp_a2d_audio_buff_free(audio_buf);
}
#endif
void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param)
{
#if CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -32,6 +32,14 @@ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);
*/
void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len);
/**
* @brief callback function for A2DP sink undecoded audio data
*
* @param [in] conn_hdl connection handle
* @param [in] audio_buf pointer to audio buff
*/
void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf);
/**
* @brief callback function for AVRCP controller
*

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -164,8 +164,23 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
assert(esp_a2d_sink_init() == ESP_OK);
esp_a2d_register_callback(&bt_app_a2d_cb);
esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb);
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE
esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb);
#else
esp_a2d_mcc_t mcc = {0};
mcc.type = ESP_A2D_MCT_SBC;
mcc.cie.sbc_info.samp_freq = 0xf;
mcc.cie.sbc_info.ch_mode = 0xf;
mcc.cie.sbc_info.block_len = 0xf;
mcc.cie.sbc_info.num_subbands = 0x3;
mcc.cie.sbc_info.alloc_mthd = 0x3;
mcc.cie.sbc_info.max_bitpool = 250;
mcc.cie.sbc_info.min_bitpool = 2;
/* register stream end point, only support mSBC currently */
esp_a2d_sink_register_stream_endpoint(0, &mcc);
esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb);
#endif
/* Get the default value of the delay value */
esp_a2d_sink_get_delay_value();
/* Get local device name */

View File

@@ -92,7 +92,7 @@ static void bt_app_task_handler(void *arg)
void bt_app_task_start_up(void)
{
bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t));
xTaskCreate(bt_app_task_handler, "BtAppT", 2048, NULL, configMAX_PRIORITIES - 3, &bt_app_task_handle);
xTaskCreate(bt_app_task_handler, "BtAppT", 4096, NULL, configMAX_PRIORITIES - 3, &bt_app_task_handle);
return;
}