feat(bt): Add a2dp_sink_stream_aac example

This commit is contained in:
yangfeng
2026-05-21 21:15:36 +08:00
parent 99d6c664be
commit 22f116eed5
14 changed files with 821 additions and 4 deletions
@@ -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
*/
@@ -63,7 +63,7 @@ void bt_a2d_evt_ext_codec_hdl(uint16_t event, void *param)
case ESP_A2D_AUDIO_CFG_EVT: {
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 (p_mcc->type == ESP_A2D_MCT_SBC) {
int sample_rate = 16000;
if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_32K) {
@@ -82,6 +82,44 @@ void bt_a2d_evt_ext_codec_hdl(uint16_t event, void *param)
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);
} else if (p_mcc->type == ESP_A2D_MCT_M24) {
int sample_rate = 16000;
if (p_mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_96K) {
sample_rate = 96000;
} else if (p_mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_88K) {
sample_rate = 88200;
} else if (p_mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_64K) {
sample_rate = 64000;
} else if (p_mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_48K) {
sample_rate = 48000;
} else if (p_mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_44K) {
sample_rate = 44100;
} else if (p_mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_32K) {
sample_rate = 32000;
} else if (p_mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_24K) {
sample_rate = 24000;
} else if (p_mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_22K) {
sample_rate = 22050;
} else if (p_mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_16K) {
sample_rate = 16000;
} else if (p_mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_12K) {
sample_rate = 12000;
} else if (p_mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_11K) {
sample_rate = 11025;
} else if (p_mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_8K) {
sample_rate = 8000;
}
ESP_LOGI(BT_AV_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x",
p_mcc->cie.m24_info.drc,
p_mcc->cie.m24_info.obj_type,
p_mcc->cie.m24_info.samp_freq1,
p_mcc->cie.m24_info.samp_freq2,
p_mcc->cie.m24_info.ch,
p_mcc->cie.m24_info.vbr,
p_mcc->cie.m24_info.br1,
p_mcc->cie.m24_info.br2,
p_mcc->cie.m24_info.br3);
ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate: %d", sample_rate);
}
break;
}
@@ -179,7 +179,7 @@ void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc)
{
ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "A2DP audio stream configuration, codec type: %d", mcc->type);
audio_sink_srv_stop();
/* for now only SBC stream is supported */
if (mcc->type == ESP_A2D_MCT_SBC) {
int sample_rate = 16000;
int ch_count = 2;
@@ -218,6 +218,64 @@ void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc)
mcc->cie.sbc_info.min_bitpool,
mcc->cie.sbc_info.max_bitpool);
ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "Audio player configured, sample rate: %d", sample_rate);
} else if (mcc->type == ESP_A2D_MCT_M24) {
int sample_rate = 16000;
int ch_count = 2;
if (mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_96K) {
sample_rate = 96000;
} else if (mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_88K) {
sample_rate = 88200;
} else if (mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_64K) {
sample_rate = 64000;
} else if (mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_48K) {
sample_rate = 48000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_44K) {
sample_rate = 44100;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_32K) {
sample_rate = 32000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_24K) {
sample_rate = 24000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_22K) {
sample_rate = 22050;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_16K) {
sample_rate = 16000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_12K) {
sample_rate = 12000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_11K) {
sample_rate = 11025;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_8K) {
sample_rate = 8000;
}
if (mcc->cie.m24_info.ch & ESP_A2D_M24_CIE_CH_1) {
ch_count = 1;
}
if (s_dac_cb.tx_chan) {
dac_continuous_del_channels(s_dac_cb.tx_chan);
s_dac_cb.tx_chan = NULL;
}
dac_continuous_config_t cont_cfg = {
.chan_mask = DAC_CHANNEL_MASK_ALL,
.desc_num = 8,
.buf_size = 2048,
.freq_hz = sample_rate,
.offset = 127,
.clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range
.chan_mode = (ch_count == 1) ? DAC_CHANNEL_MODE_SIMUL : DAC_CHANNEL_MODE_ALTER,
};
/* Allocate continuous channels */
ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &s_dac_cb.tx_chan));
ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x",
mcc->cie.m24_info.drc,
mcc->cie.m24_info.obj_type,
mcc->cie.m24_info.samp_freq1,
mcc->cie.m24_info.samp_freq2,
mcc->cie.m24_info.ch,
mcc->cie.m24_info.vbr,
mcc->cie.m24_info.br1,
mcc->cie.m24_info.br2,
mcc->cie.m24_info.br3);
ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "Audio player configured, sample rate: %d", sample_rate);
}
}
@@ -189,7 +189,7 @@ void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc)
{
ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "A2DP audio stream configuration, codec type: %d", mcc->type);
audio_sink_srv_stop();
/* for now only SBC stream is supported */
if (mcc->type == ESP_A2D_MCT_SBC) {
int sample_rate = 16000;
int ch_count = 2;
@@ -217,6 +217,53 @@ void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc)
mcc->cie.sbc_info.min_bitpool,
mcc->cie.sbc_info.max_bitpool);
ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "Audio player configured, sample rate: %d", sample_rate);
} else if (mcc->type == ESP_A2D_MCT_M24) {
int sample_rate = 16000;
int ch_count = 2;
if (mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_96K) {
sample_rate = 96000;
} else if (mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_88K) {
sample_rate = 88200;
} else if (mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_64K) {
sample_rate = 64000;
} else if (mcc->cie.m24_info.samp_freq2 & ESP_A2D_M24_CIE_SF2_48K) {
sample_rate = 48000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_44K) {
sample_rate = 44100;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_32K) {
sample_rate = 32000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_24K) {
sample_rate = 24000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_22K) {
sample_rate = 22050;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_16K) {
sample_rate = 16000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_12K) {
sample_rate = 12000;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_11K) {
sample_rate = 11025;
} else if (mcc->cie.m24_info.samp_freq1 & ESP_A2D_M24_CIE_SF1_8K) {
sample_rate = 8000;
}
if (mcc->cie.m24_info.ch & ESP_A2D_M24_CIE_CH_1) {
ch_count = 1;
}
i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate);
i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, ch_count);
ESP_ERROR_CHECK(i2s_channel_reconfig_std_clock(s_i2s_cb.tx_chan, &clk_cfg));
ESP_ERROR_CHECK(i2s_channel_reconfig_std_slot(s_i2s_cb.tx_chan, &slot_cfg));
ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x-0x%x",
mcc->cie.m24_info.drc,
mcc->cie.m24_info.obj_type,
mcc->cie.m24_info.samp_freq1,
mcc->cie.m24_info.samp_freq2,
mcc->cie.m24_info.ch,
mcc->cie.m24_info.vbr,
mcc->cie.m24_info.br1,
mcc->cie.m24_info.br2,
mcc->cie.m24_info.br3);
ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "Audio player configured, sample rate: %d", sample_rate);
}
}