Skip to content

Commit 1ab021e

Browse files
committed
Fix Warnings for IDF 5.5
1 parent 2e0f47d commit 1ab021e

File tree

3 files changed

+242
-16
lines changed

3 files changed

+242
-16
lines changed

src/BluetoothA2DPCommon.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class BluetoothA2DPCommon {
283283
void set_task_priority(UBaseType_t priority) { task_priority = priority; }
284284

285285
/// Defines the core which is used to start the tasks (to process the events
286-
/// and audio queue)
286+
/// and audio queue): default is 1
287287
void set_task_core(BaseType_t core) { task_core = core; }
288288

289289
/// Defines the queue size of the event task

src/BluetoothA2DPSink.cpp

Lines changed: 209 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ extern "C" void ccall_av_hdl_a2d_evt(uint16_t event, void *param) {
4444
}
4545
}
4646

47+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
48+
extern "C" void ccall_audio_encoded_callback(esp_a2d_conn_hdl_t conn_hdl,
49+
esp_a2d_audio_buff_t *audio_buf) {
50+
ESP_LOGI(BT_AV_TAG, "ccall_audio_encoded_callback");
51+
if (actual_bluetooth_a2dp_sink &&
52+
actual_bluetooth_a2dp_sink->encoded_stream_reader && audio_buf) {
53+
// pass raw encoded bytes
54+
ESP_LOGI(BT_AV_TAG, "encoded_stream_reader=%d", (int)audio_buf->data_len);
55+
actual_bluetooth_a2dp_sink->encoded_stream_reader(audio_buf->data,
56+
audio_buf->data_len);
57+
}
58+
if (audio_buf) {
59+
esp_a2d_audio_buff_free(audio_buf);
60+
}
61+
}
62+
#endif
63+
4764
/**
4865
* Constructor
4966
*/
@@ -132,7 +149,6 @@ void BluetoothA2DPSink::start(const char *name) {
132149
// Initialize NVS
133150
init_nvs();
134151
if (is_autoreconnect_allowed) {
135-
136152
// reconnect management
137153
// grab last connnectiom, even if we dont use it now for auto reconnect
138154
get_last_connection();
@@ -192,6 +208,83 @@ void BluetoothA2DPSink::init_i2s() {
192208

193209
esp_a2d_mct_t BluetoothA2DPSink::get_audio_type() { return audio_type; }
194210

211+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
212+
213+
bool BluetoothA2DPSink::set_codec(A2DPCodec codec,
214+
void (*encoded_cb)(const uint8_t *data,
215+
size_t len)) {
216+
encoded_stream_reader = encoded_cb;
217+
ESP_LOGI(BT_AV_TAG, "set_codec() called with codec=%d", codec);
218+
is_output = false;
219+
desired_codec = codec;
220+
ESP_LOGD(BT_AV_TAG, "set_codec: is_bluedroid_initialized=%d",
221+
is_bluedroid_initialized);
222+
if (!is_bluedroid_initialized) {
223+
ESP_LOGD(BT_AV_TAG,
224+
"set_codec: will register later (bluetooth not initialized)");
225+
return true; // will register later
226+
}
227+
ESP_LOGD(BT_AV_TAG, "set_codec: codec_sep_registered=%d",
228+
codec_sep_registered);
229+
if (codec_sep_registered) {
230+
ESP_LOGD(BT_AV_TAG, "set_codec: SEP already registered");
231+
return true;
232+
}
233+
esp_a2d_mcc_t mcc{};
234+
ESP_LOGD(BT_AV_TAG, "set_codec: preparing mcc struct");
235+
switch (codec) {
236+
case A2DP_CODEC_SBC:
237+
mcc.type = ESP_A2D_MCT_SBC;
238+
mcc.cie.sbc_info.samp_freq =
239+
ESP_A2D_SBC_CIE_SF_44K | ESP_A2D_SBC_CIE_SF_48K;
240+
mcc.cie.sbc_info.ch_mode =
241+
ESP_A2D_SBC_CIE_CH_MODE_STEREO | ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO;
242+
mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_16;
243+
mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS;
244+
mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_8;
245+
mcc.cie.sbc_info.min_bitpool = 2;
246+
mcc.cie.sbc_info.max_bitpool = 250;
247+
break;
248+
case A2DP_CODEC_M12:
249+
mcc.type = ESP_A2D_MCT_M12; // may not be supported
250+
break;
251+
case A2DP_CODEC_AAC:
252+
mcc.type = ESP_A2D_MCT_M24; // AAC (MPEG-2/4) - may not be supported
253+
break;
254+
case A2DP_CODEC_ATRAC:
255+
mcc.type = ESP_A2D_MCT_ATRAC; // may not be supported
256+
break;
257+
}
258+
ESP_LOGI(BT_AV_TAG,
259+
"set_codec: calling esp_a2d_sink_register_stream_endpoint");
260+
esp_err_t err = esp_a2d_sink_register_stream_endpoint(0, &mcc);
261+
ESP_LOGD(BT_AV_TAG,
262+
"set_codec: esp_a2d_sink_register_stream_endpoint returned %d", err);
263+
if (err == ESP_OK) {
264+
codec_sep_registered = true;
265+
ESP_LOGI(BT_AV_TAG, "Registered SEP for codec type %d", mcc.type);
266+
if (encoded_cb) {
267+
ESP_LOGD(BT_AV_TAG, "set_codec: encoded_cb provided");
268+
esp_err_t cb_err = esp_a2d_sink_register_audio_data_callback(
269+
ccall_audio_encoded_callback);
270+
ESP_LOGI(
271+
BT_AV_TAG,
272+
"set_codec: esp_a2d_sink_register_audio_data_callback returned %d",
273+
cb_err);
274+
if (cb_err != ESP_OK) {
275+
ESP_LOGW(BT_AV_TAG, "Failed to register encoded audio callback");
276+
}
277+
}
278+
279+
return true;
280+
} else {
281+
ESP_LOGW(BT_AV_TAG, "Failed to register SEP codec %d err=%d", mcc.type,
282+
err);
283+
return false;
284+
}
285+
}
286+
#endif
287+
195288
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
196289
const char *BluetoothA2DPSink::get_connected_source_name() {
197290
if (is_connected()) {
@@ -409,9 +502,20 @@ void BluetoothA2DPSink::app_rc_ct_callback(esp_avrc_ct_cb_event_t event,
409502
sizeof(esp_avrc_ct_cb_param_t));
410503
break;
411504
}
505+
#endif
506+
507+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
412508

509+
case ESP_AVRC_CT_PROF_STATE_EVT: {
510+
ESP_LOGD(BT_AV_TAG, "%s ESP_AVRC_CT_PROF_STATE_EVT",
511+
__func__);
512+
app_work_dispatch(ccall_av_hdl_avrc_evt, event, param,
513+
sizeof(esp_avrc_ct_cb_param_t));
514+
break;
515+
}
413516
#endif
414517

518+
415519
default:
416520
ESP_LOGE(BT_AV_TAG, "Invalid AVRC event: %d", event);
417521
break;
@@ -465,26 +569,77 @@ void BluetoothA2DPSink::handle_audio_cfg(uint16_t event, void *p_param) {
465569
a2d->audio_cfg.mcc.type);
466570

467571
// determine sample rate
468-
m_sample_rate = 16000;
572+
int sample_rate = 0;
573+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
574+
// Use new sbc_info (avoid deprecated sbc[] array)
575+
uint8_t sf = a2d->audio_cfg.mcc.cie.sbc_info.samp_freq;
576+
#ifdef ESP_A2D_SBC_CIE_SF_32K
577+
if (sf & ESP_A2D_SBC_CIE_SF_32K) {
578+
sample_rate = 32000;
579+
} else
580+
#endif
581+
if (sf & ESP_A2D_SBC_CIE_SF_44K) {
582+
sample_rate = 44100;
583+
} else if (sf & ESP_A2D_SBC_CIE_SF_48K) {
584+
sample_rate = 48000;
585+
}
586+
#else
587+
// Legacy field parsing (older IDF)
469588
char oct0 = a2d->audio_cfg.mcc.cie.sbc[0];
470589
if (oct0 & (0x01 << 6)) {
471-
m_sample_rate = 32000;
590+
sample_rate = 32000;
472591
} else if (oct0 & (0x01 << 5)) {
473-
m_sample_rate = 44100;
592+
sample_rate = 44100;
474593
} else if (oct0 & (0x01 << 4)) {
475-
m_sample_rate = 48000;
476-
}
477-
ESP_LOGI(BT_AV_TAG, "a2dp audio_cfg_cb , sample_rate %d", m_sample_rate);
478-
if (sample_rate_callback != nullptr) {
479-
sample_rate_callback(m_sample_rate);
594+
sample_rate = 48000;
480595
}
596+
#endif
481597

482598
// for now only SBC stream is supported
483599
if (a2d->audio_cfg.mcc.type == ESP_A2D_MCT_SBC) {
600+
// determine channel count from negotiated SBC channel mode
601+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
602+
uint8_t ch_mode = a2d->audio_cfg.mcc.cie.sbc_info.ch_mode;
603+
if (ch_mode == ESP_A2D_SBC_CIE_CH_MODE_MONO) {
604+
m_channels = 1;
605+
} else {
606+
m_channels = 2; // dual/stereo/joint are all rendered as 2 channels
607+
}
608+
#else
609+
// legacy parsing: octet 1 bits 0..3 represent channel mode; only one is set
610+
uint8_t oct1 = a2d->audio_cfg.mcc.cie.sbc[1];
611+
// Bit masks per A2DP spec for channel mode (mono bit3, dual bit2, stereo
612+
// bit1, joint bit0)
613+
if (oct1 & 0x08) {
614+
m_channels = 1; // mono
615+
} else {
616+
m_channels = 2; // any other mode
617+
}
618+
#endif
619+
ESP_LOGI(BT_AV_TAG, "a2dp audio_cfg_cb , channels %d", m_channels);
620+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
484621
ESP_LOGI(BT_AV_TAG, "configure audio player %x-%x-%x-%x\n",
485-
a2d->audio_cfg.mcc.cie.sbc[0], a2d->audio_cfg.mcc.cie.sbc[1],
486-
a2d->audio_cfg.mcc.cie.sbc[2], a2d->audio_cfg.mcc.cie.sbc[3]);
622+
(int)a2d->audio_cfg.mcc.cie.sbc_info.samp_freq,
623+
(int)a2d->audio_cfg.mcc.cie.sbc_info.ch_mode,
624+
(int)a2d->audio_cfg.mcc.cie.sbc_info.block_len,
625+
(int)a2d->audio_cfg.mcc.cie.sbc_info.alloc_mthd);
626+
#else
627+
ESP_LOGI(
628+
BT_AV_TAG, "configure audio player %x-%x-%x-%x\n",
629+
(int)a2d->audio_cfg.mcc.cie.sbc[0], (int)a2d->audio_cfg.mcc.cie.sbc[1],
630+
(int)a2d->audio_cfg.mcc.cie.sbc[2], (int)a2d->audio_cfg.mcc.cie.sbc[3]);
631+
#endif
487632

633+
ESP_LOGI(BT_AV_TAG, "a2dp audio_cfg_cb , sample_rate %u", m_sample_rate);
634+
}
635+
636+
// inform caller about new values
637+
if (sample_rate != 0) {
638+
m_sample_rate = sample_rate;
639+
// act on determined data
640+
if (sample_rate_callback != nullptr) {
641+
sample_rate_callback(m_sample_rate);
642+
}
488643
out->set_sample_rate(m_sample_rate);
489644
}
490645
}
@@ -831,6 +986,22 @@ void BluetoothA2DPSink::av_hdl_avrc_evt(uint16_t event, void *p_param) {
831986

832987
#endif
833988

989+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
990+
991+
/* when avrcp controller init or deinit completed, this event comes */
992+
case ESP_AVRC_CT_PROF_STATE_EVT: {
993+
if (ESP_AVRC_INIT_SUCCESS == rc->avrc_ct_init_stat.state) {
994+
ESP_LOGI(BT_RC_CT_TAG, "AVRCP CT STATE: Init Complete");
995+
} else if (ESP_AVRC_DEINIT_SUCCESS == rc->avrc_ct_init_stat.state) {
996+
ESP_LOGI(BT_RC_CT_TAG, "AVRCP CT STATE: Deinit Complete");
997+
} else {
998+
ESP_LOGE(BT_RC_CT_TAG, "AVRCP CT STATE error: %d", rc->avrc_ct_init_stat.state);
999+
}
1000+
break;
1001+
}
1002+
#endif
1003+
1004+
8341005
default:
8351006
ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event);
8361007
break;
@@ -893,6 +1064,13 @@ void BluetoothA2DPSink::av_hdl_stack_evt(uint16_t event, void *p_param) {
8931064
ESP_LOGE(BT_AV_TAG, "esp_a2d_sink_init");
8941065
}
8951066

1067+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
1068+
// Register only later when user sets a callback
1069+
if (!codec_sep_registered && encoded_stream_reader != nullptr) {
1070+
set_codec(desired_codec, encoded_stream_reader);
1071+
}
1072+
#endif
1073+
8961074
// start automatic reconnect if relevant and stack is up
8971075
if (reconnect_status == AutoReconnect && has_last_connection()) {
8981076
ESP_LOGD(BT_AV_TAG, "reconnect");
@@ -1105,8 +1283,7 @@ size_t BluetoothA2DPSink::i2s_write_data(const uint8_t *data,
11051283
int open = item_size;
11061284
int processed = 0;
11071285
while (open > 0) {
1108-
int written =
1109-
out->write(data + processed, std::min(open, max_write_size));
1286+
int written = out->write(data + processed, std::min(open, max_write_size));
11101287
open -= written;
11111288
processed += written;
11121289
// add some delay between the writes
@@ -1129,7 +1306,10 @@ void BluetoothA2DPSink::app_rc_tg_callback(esp_avrc_tg_cb_event_t event,
11291306
case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT:
11301307
case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT:
11311308
case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT:
1132-
case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT: {
1309+
case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT:
1310+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
1311+
case ESP_AVRC_TG_PROF_STATE_EVT: {
1312+
#endif
11331313
app_work_dispatch(ccall_av_hdl_avrc_tg_evt, event, param,
11341314
sizeof(esp_avrc_tg_cb_param_t));
11351315
break;
@@ -1219,6 +1399,21 @@ void BluetoothA2DPSink::av_hdl_avrc_tg_evt(uint16_t event, void *p_param) {
12191399
break;
12201400
}
12211401

1402+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
1403+
1404+
/* when avrcp target init or deinit completed, this event comes */
1405+
case ESP_AVRC_TG_PROF_STATE_EVT: {
1406+
if (ESP_AVRC_INIT_SUCCESS == rc->avrc_tg_init_stat.state) {
1407+
ESP_LOGI(BT_RC_CT_TAG, "AVRCP TG STATE: Init Complete");
1408+
} else if (ESP_AVRC_DEINIT_SUCCESS == rc->avrc_tg_init_stat.state) {
1409+
ESP_LOGI(BT_RC_CT_TAG, "AVRCP TG STATE: Deinit Complete");
1410+
} else {
1411+
ESP_LOGE(BT_RC_CT_TAG, "AVRCP TG STATE error: %d", rc->avrc_tg_init_stat.state);
1412+
}
1413+
break;
1414+
}
1415+
#endif
1416+
12221417
default:
12231418
ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event);
12241419
break;

0 commit comments

Comments
 (0)