forked from espressif/esp-idf
feat(examples): Add kconfig option for a2dp_sink example to use new audio APIs
This commit is contained in:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
*
|
*
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user