mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(bt): Fix compatibility with A2DP API legacy usage methods
- Modify the timing of API calls in the A2DP example - Add a2dp_stream_aac test case - Closes https://github.com/espressif/esp-idf/issues/18786
This commit is contained in:
@@ -68,10 +68,57 @@ static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
|
||||
bredr_app_gap_evt_def_hdl(event, param);
|
||||
}
|
||||
|
||||
static void bt_app_a2d_evt_hdl(uint16_t event, void *param)
|
||||
{
|
||||
esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)(param);
|
||||
|
||||
switch (event) {
|
||||
/* when a2dp init or deinit completed, this event comes */
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete");
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == TRUE
|
||||
esp_a2d_mcc_t mcc = {0};
|
||||
mcc.type = ESP_A2D_MCT_SBC;
|
||||
mcc.cie.sbc_info.samp_freq = ESP_A2D_SBC_CIE_SF_16K |
|
||||
ESP_A2D_SBC_CIE_SF_32K |
|
||||
ESP_A2D_SBC_CIE_SF_44K |
|
||||
ESP_A2D_SBC_CIE_SF_48K;
|
||||
mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_STEREO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO;
|
||||
mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_8 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_12 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_16;
|
||||
mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8;
|
||||
mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc.cie.sbc_info.max_bitpool = 250;
|
||||
mcc.cie.sbc_info.min_bitpool = 2;
|
||||
ESP_ERROR_CHECK(esp_a2d_sink_register_stream_endpoint(0, &mcc));
|
||||
#endif
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
} else {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* others */
|
||||
default:
|
||||
ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_A2D_PROF_STATE_EVT:
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_app_a2d_evt_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
@@ -124,31 +171,9 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
#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 = ESP_A2D_SBC_CIE_SF_16K |
|
||||
ESP_A2D_SBC_CIE_SF_32K |
|
||||
ESP_A2D_SBC_CIE_SF_44K |
|
||||
ESP_A2D_SBC_CIE_SF_48K;
|
||||
mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_STEREO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO;
|
||||
mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_8 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_12 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_16;
|
||||
mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8;
|
||||
mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc.cie.sbc_info.max_bitpool = 250;
|
||||
mcc.cie.sbc_info.min_bitpool = 2;
|
||||
/* register stream end point, only support SBC 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 */
|
||||
esp_bt_gap_get_device_name();
|
||||
|
||||
|
||||
@@ -369,7 +369,7 @@ static void bt_app_register_a2dp_sink_seps(void)
|
||||
mcc_aac.cie.m24_info.br1 = 0x7F & ESP_A2D_M24_CIE_BR1_MSK;
|
||||
mcc_aac.cie.m24_info.br2 = 0xFF & ESP_A2D_M24_CIE_BR2_MSK;
|
||||
mcc_aac.cie.m24_info.br3 = 0xFF & ESP_A2D_M24_CIE_BR3_MSK;
|
||||
esp_a2d_sink_register_stream_endpoint(0, &mcc_aac);
|
||||
ESP_ERROR_CHECK(esp_a2d_sink_register_stream_endpoint(0, &mcc_aac));
|
||||
|
||||
esp_a2d_mcc_t mcc_sbc = {0};
|
||||
mcc_sbc.type = ESP_A2D_MCT_SBC;
|
||||
@@ -389,7 +389,7 @@ static void bt_app_register_a2dp_sink_seps(void)
|
||||
mcc_sbc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc_sbc.cie.sbc_info.min_bitpool = 2;
|
||||
mcc_sbc.cie.sbc_info.max_bitpool = 250;
|
||||
esp_a2d_sink_register_stream_endpoint(1, &mcc_sbc);
|
||||
ESP_ERROR_CHECK(esp_a2d_sink_register_stream_endpoint(1, &mcc_sbc));
|
||||
}
|
||||
|
||||
static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param)
|
||||
@@ -407,7 +407,18 @@ static void bt_app_a2d_hdl(uint16_t event, void *param)
|
||||
esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)param;
|
||||
|
||||
switch (event) {
|
||||
case ESP_A2D_PROF_STATE_EVT:
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete");
|
||||
bt_app_register_a2dp_sink_seps();
|
||||
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
} else {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
@@ -504,11 +515,8 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
esp_a2d_register_callback(&bt_app_a2d_cb);
|
||||
assert(esp_a2d_sink_init() == ESP_OK);
|
||||
|
||||
bt_app_register_a2dp_sink_seps();
|
||||
esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb);
|
||||
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
/* Get local device name */
|
||||
esp_bt_gap_get_device_name();
|
||||
|
||||
|
||||
@@ -338,7 +338,7 @@ static void bt_app_register_a2dp_src_seps(void)
|
||||
mcc_aac.cie.m24_info.br1 = 0x02 & ESP_A2D_M24_CIE_BR1_MSK;
|
||||
mcc_aac.cie.m24_info.br2 = 0x71 & ESP_A2D_M24_CIE_BR2_MSK;
|
||||
mcc_aac.cie.m24_info.br3 = 0x00 & ESP_A2D_M24_CIE_BR3_MSK;
|
||||
esp_a2d_source_register_stream_endpoint(0, &mcc_aac);
|
||||
ESP_ERROR_CHECK(esp_a2d_source_register_stream_endpoint(0, &mcc_aac));
|
||||
|
||||
esp_a2d_mcc_t mcc_sbc = {0};
|
||||
mcc_sbc.type = ESP_A2D_MCT_SBC;
|
||||
@@ -358,7 +358,28 @@ static void bt_app_register_a2dp_src_seps(void)
|
||||
mcc_sbc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc_sbc.cie.sbc_info.min_bitpool = 2;
|
||||
mcc_sbc.cie.sbc_info.max_bitpool = 250;
|
||||
esp_a2d_source_register_stream_endpoint(1, &mcc_sbc);
|
||||
ESP_ERROR_CHECK(esp_a2d_source_register_stream_endpoint(1, &mcc_sbc));
|
||||
}
|
||||
|
||||
static void bt_app_a2d_prof_hdl(uint16_t event, void *param)
|
||||
{
|
||||
esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)param;
|
||||
|
||||
switch (event) {
|
||||
/* when a2dp init or deinit completed, this event comes */
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete");
|
||||
bt_app_register_a2dp_src_seps();
|
||||
} else {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
@@ -378,8 +399,6 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
esp_a2d_source_init();
|
||||
esp_a2d_register_callback(&bt_app_a2d_cb);
|
||||
|
||||
bt_app_register_a2dp_src_seps();
|
||||
|
||||
/* Avoid the state error of s_a2d_state caused by the connection initiated by the peer device. */
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);
|
||||
esp_bt_gap_get_device_name();
|
||||
@@ -407,7 +426,16 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
|
||||
static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
{
|
||||
bt_app_work_dispatch(bt_app_av_sm_hdlr, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
switch (event) {
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_app_a2d_prof_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
bt_app_work_dispatch(bt_app_av_sm_hdlr, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_app_a2d_heart_beat(TimerHandle_t arg)
|
||||
|
||||
@@ -47,6 +47,7 @@ static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *pa
|
||||
static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param);
|
||||
|
||||
/* callback function for A2DP sink */
|
||||
static void bt_app_a2d_evt_hdl(uint16_t event, void *param);
|
||||
static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);
|
||||
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE
|
||||
@@ -82,10 +83,59 @@ static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
|
||||
bredr_app_gap_evt_def_hdl(event, param);
|
||||
}
|
||||
|
||||
static void bt_app_a2d_evt_hdl(uint16_t event, void *param)
|
||||
{
|
||||
esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)(param);
|
||||
|
||||
switch (event) {
|
||||
/* when a2dp init or deinit completed, this event comes */
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete");
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == TRUE
|
||||
esp_a2d_mcc_t mcc = {0};
|
||||
mcc.type = ESP_A2D_MCT_SBC;
|
||||
mcc.cie.sbc_info.samp_freq = ESP_A2D_SBC_CIE_SF_16K |
|
||||
ESP_A2D_SBC_CIE_SF_32K |
|
||||
ESP_A2D_SBC_CIE_SF_44K |
|
||||
ESP_A2D_SBC_CIE_SF_48K;
|
||||
mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_STEREO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO;
|
||||
mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_8 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_12 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_16;
|
||||
mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8;
|
||||
mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc.cie.sbc_info.max_bitpool = 250;
|
||||
mcc.cie.sbc_info.min_bitpool = 2;
|
||||
ESP_ERROR_CHECK(esp_a2d_sink_register_stream_endpoint(0, &mcc));
|
||||
#endif
|
||||
#endif
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
} else {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* others */
|
||||
default:
|
||||
ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_A2D_PROF_STATE_EVT:
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_app_a2d_evt_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
@@ -194,32 +244,10 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
#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 = ESP_A2D_SBC_CIE_SF_16K |
|
||||
ESP_A2D_SBC_CIE_SF_32K |
|
||||
ESP_A2D_SBC_CIE_SF_44K |
|
||||
ESP_A2D_SBC_CIE_SF_48K;
|
||||
mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_STEREO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO;
|
||||
mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_8 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_12 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_16;
|
||||
mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8;
|
||||
mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc.cie.sbc_info.max_bitpool = 250;
|
||||
mcc.cie.sbc_info.min_bitpool = 2;
|
||||
/* register stream end point, only support SBC currently */
|
||||
esp_a2d_sink_register_stream_endpoint(0, &mcc);
|
||||
esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
/* Get local device name */
|
||||
esp_bt_gap_get_device_name();
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "esp_a2dp_api.h"
|
||||
#include "esp_avrc_api.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@@ -108,10 +109,59 @@ static void bt_app_avrc_ct_evt_hdl(uint16_t event, void *param)
|
||||
* EXTERNAL FUNCTION DEFINITIONS
|
||||
*******************************/
|
||||
|
||||
static void bt_app_a2d_evt_hdl(uint16_t event, void *param)
|
||||
{
|
||||
esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)(param);
|
||||
|
||||
switch (event) {
|
||||
/* when a2dp init or deinit completed, this event comes */
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete");
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == TRUE
|
||||
esp_a2d_mcc_t mcc = {0};
|
||||
mcc.type = ESP_A2D_MCT_SBC;
|
||||
mcc.cie.sbc_info.samp_freq = ESP_A2D_SBC_CIE_SF_16K |
|
||||
ESP_A2D_SBC_CIE_SF_32K |
|
||||
ESP_A2D_SBC_CIE_SF_44K |
|
||||
ESP_A2D_SBC_CIE_SF_48K;
|
||||
mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_STEREO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO;
|
||||
mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_8 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_12 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_16;
|
||||
mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8;
|
||||
mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc.cie.sbc_info.max_bitpool = 250;
|
||||
mcc.cie.sbc_info.min_bitpool = 2;
|
||||
ESP_ERROR_CHECK(esp_a2d_sink_register_stream_endpoint(0, &mcc));
|
||||
#endif
|
||||
#endif
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
} else {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* others */
|
||||
default:
|
||||
ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_A2D_PROF_STATE_EVT:
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_app_a2d_evt_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -79,32 +79,10 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
#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 = ESP_A2D_SBC_CIE_SF_16K |
|
||||
ESP_A2D_SBC_CIE_SF_32K |
|
||||
ESP_A2D_SBC_CIE_SF_44K |
|
||||
ESP_A2D_SBC_CIE_SF_48K;
|
||||
mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_STEREO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO;
|
||||
mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_8 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_12 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_16;
|
||||
mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8;
|
||||
mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc.cie.sbc_info.max_bitpool = 250;
|
||||
mcc.cie.sbc_info.min_bitpool = 2;
|
||||
/* register stream end point, only support SBC currently */
|
||||
esp_a2d_sink_register_stream_endpoint(0, &mcc);
|
||||
esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
/* Get local device name */
|
||||
esp_bt_gap_get_device_name();
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *pa
|
||||
static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param);
|
||||
|
||||
/* callback function for A2DP sink */
|
||||
static void bt_app_a2d_evt_hdl(uint16_t event, void *param);
|
||||
static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);
|
||||
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE
|
||||
@@ -85,10 +86,59 @@ static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
|
||||
bredr_app_gap_evt_def_hdl(event, param);
|
||||
}
|
||||
|
||||
static void bt_app_a2d_evt_hdl(uint16_t event, void *param)
|
||||
{
|
||||
esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)(param);
|
||||
|
||||
switch (event) {
|
||||
/* when a2dp init or deinit completed, this event comes */
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete");
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == TRUE
|
||||
esp_a2d_mcc_t mcc = {0};
|
||||
mcc.type = ESP_A2D_MCT_SBC;
|
||||
mcc.cie.sbc_info.samp_freq = ESP_A2D_SBC_CIE_SF_16K |
|
||||
ESP_A2D_SBC_CIE_SF_32K |
|
||||
ESP_A2D_SBC_CIE_SF_44K |
|
||||
ESP_A2D_SBC_CIE_SF_48K;
|
||||
mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_STEREO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO;
|
||||
mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_8 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_12 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_16;
|
||||
mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8;
|
||||
mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc.cie.sbc_info.max_bitpool = 250;
|
||||
mcc.cie.sbc_info.min_bitpool = 2;
|
||||
ESP_ERROR_CHECK(esp_a2d_sink_register_stream_endpoint(0, &mcc));
|
||||
#endif
|
||||
#endif
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
} else {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* others */
|
||||
default:
|
||||
ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_A2D_PROF_STATE_EVT:
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_app_a2d_evt_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
@@ -242,32 +292,10 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
#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 = ESP_A2D_SBC_CIE_SF_16K |
|
||||
ESP_A2D_SBC_CIE_SF_32K |
|
||||
ESP_A2D_SBC_CIE_SF_44K |
|
||||
ESP_A2D_SBC_CIE_SF_48K;
|
||||
mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_STEREO |
|
||||
ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO;
|
||||
mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_8 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_12 |
|
||||
ESP_A2D_SBC_CIE_BLOCK_LEN_16;
|
||||
mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8;
|
||||
mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
|
||||
mcc.cie.sbc_info.max_bitpool = 250;
|
||||
mcc.cie.sbc_info.min_bitpool = 2;
|
||||
/* register stream end point, only support SBC currently */
|
||||
esp_a2d_sink_register_stream_endpoint(0, &mcc);
|
||||
esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
/* Get local device name */
|
||||
esp_bt_gap_get_device_name();
|
||||
|
||||
|
||||
@@ -210,3 +210,37 @@ def test_bt_avrcp_absolute_volume(app_path: str, dut: tuple[IdfDut, IdfDut]) ->
|
||||
sink_dut.expect_exact(f'AVRC conn_state event: state 1, [{source_dut_mac}]', timeout=30)
|
||||
sink_dut.expect_exact(f'AVRC conn_state evt: state 1, [{source_dut_mac}]', timeout=30)
|
||||
sink_dut.expect_exact('start volume change simulation', timeout=30)
|
||||
|
||||
|
||||
# case 8: A2DP Stream AAC
|
||||
@pytest.mark.two_duts
|
||||
@pytest.mark.parametrize(
|
||||
'count, app_path, target, config',
|
||||
[
|
||||
(
|
||||
2,
|
||||
f'{str(CUR_DIR / "a2dp_sink_stream_aac")}|{str(CUR_DIR / "a2dp_source_aac")}',
|
||||
'esp32|esp32',
|
||||
'test',
|
||||
),
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_bt_a2dp_stream_aac(app_path: str, dut: tuple[IdfDut, IdfDut]) -> None:
|
||||
sink_dut = dut[0]
|
||||
source_dut = dut[1]
|
||||
source_dut_mac = source_dut.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8')
|
||||
sink_dut.expect_exact('A2DP PROF STATE: Init Complete', timeout=30)
|
||||
source_dut.expect_exact('A2DP PROF STATE: Init Complete', timeout=30)
|
||||
sink_dut.expect_exact('A2DP register SEP success, seid: 0', timeout=30)
|
||||
sink_dut.expect_exact('A2DP register SEP success, seid: 1', timeout=30)
|
||||
|
||||
source_dut.expect_exact('Found a target device', timeout=60)
|
||||
source_dut.expect_exact('a2dp connecting to peer:', timeout=30)
|
||||
source_dut.expect_exact('A2DP audio stream configuration, codec type: 2', timeout=30)
|
||||
source_dut.expect_exact('a2dp connected', timeout=30)
|
||||
source_dut.expect_exact('a2dp media start successfully.', timeout=60)
|
||||
|
||||
sink_dut.expect_exact('A2DP audio stream configuration, codec type: 2', timeout=30)
|
||||
sink_dut.expect_exact(f'A2DP connection state: Connected, [{source_dut_mac}]', timeout=30)
|
||||
sink_dut.expect_exact('A2DP audio state: Started', timeout=60)
|
||||
|
||||
@@ -82,6 +82,30 @@ static void bt_app_avrc_ct_evt_hdl(uint16_t event, void *param)
|
||||
}
|
||||
}
|
||||
|
||||
/* handler for A2DP callback events */
|
||||
static void bt_app_a2d_evt_hdl(uint16_t event, void *param)
|
||||
{
|
||||
esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)(param);
|
||||
|
||||
switch (event) {
|
||||
/* when a2dp init or deinit completed, this event comes */
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete");
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
} else {
|
||||
ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* others */
|
||||
default:
|
||||
ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************
|
||||
* EXTERNAL FUNCTION DEFINITIONS
|
||||
*******************************/
|
||||
@@ -89,13 +113,16 @@ static void bt_app_avrc_ct_evt_hdl(uint16_t event, void *param)
|
||||
void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_A2D_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_app_a2d_evt_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_CONNECTION_STATE_EVT:
|
||||
case ESP_A2D_AUDIO_STATE_EVT:
|
||||
case ESP_A2D_AUDIO_CFG_EVT: {
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_PROF_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: {
|
||||
|
||||
@@ -644,9 +644,6 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
esp_a2d_register_callback(&bt_app_a2d_cb);
|
||||
esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb);
|
||||
|
||||
/* Get the default value of the delay value */
|
||||
esp_a2d_sink_get_delay_value();
|
||||
|
||||
/* set discoverable and connectable mode, wait to be connected */
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user