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 help
This enables the AVRCP Cover Art feature in example and try to get cover art image from peer device. 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 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 * 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 */ /* when audio codec is configured, this event comes */
case ESP_A2D_AUDIO_CFG_EVT: { case ESP_A2D_AUDIO_CFG_EVT: {
a2d = (esp_a2d_cb_param_t *)(p_param); 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 */ /* 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 sample_rate = 16000;
int ch_count = 2; int ch_count = 2;
char oct0 = a2d->audio_cfg.mcc.cie.sbc[0]; if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_32K) {
if (oct0 & (0x01 << 6)) {
sample_rate = 32000; 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; 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; 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; ch_count = 1;
} }
#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC #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_reconfig_std_slot(tx_chan, &slot_cfg);
i2s_channel_enable(tx_chan); i2s_channel_enable(tx_chan);
#endif #endif
ESP_LOGI(BT_AV_TAG, "Configure audio player: %x-%x-%x-%x", ESP_LOGI(BT_AV_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-%d-%d",
a2d->audio_cfg.mcc.cie.sbc[0], p_mcc->cie.sbc_info.samp_freq,
a2d->audio_cfg.mcc.cie.sbc[1], p_mcc->cie.sbc_info.ch_mode,
a2d->audio_cfg.mcc.cie.sbc[2], p_mcc->cie.sbc_info.block_len,
a2d->audio_cfg.mcc.cie.sbc[3]); 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); ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate: %d", sample_rate);
} }
break; break;
@@ -381,6 +384,17 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param)
} }
break; 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 */ /* When protocol service capabilities configured, this event comes */
case ESP_A2D_SNK_PSC_CFG_EVT: { case ESP_A2D_SNK_PSC_CFG_EVT: {
a2d = (esp_a2d_cb_param_t *)(p_param); 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_STATE_EVT:
case ESP_A2D_AUDIO_CFG_EVT: case ESP_A2D_AUDIO_CFG_EVT:
case ESP_A2D_PROF_STATE_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_PSC_CFG_EVT:
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
case ESP_A2D_SNK_GET_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) void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
{ {
write_ringbuf(data, 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) 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 #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 * 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); 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 * @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 * 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); assert(esp_a2d_sink_init() == ESP_OK);
esp_a2d_register_callback(&bt_app_a2d_cb); 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 */ /* Get the default value of the delay value */
esp_a2d_sink_get_delay_value(); esp_a2d_sink_get_delay_value();
/* Get local device name */ /* 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) void bt_app_task_start_up(void)
{ {
bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t)); 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; return;
} }