20#include "BluetoothA2DPOutput.h"
21#include "freertos/ringbuf.h"
24#ifndef A2DP_I2S_AUDIOTOOLS
25#warning "AudioTools library is not included first or installed"
28#define APP_SIG_WORK_DISPATCH (0x01)
31#define BT_AV_TAG "BT_AV"
34#if (A2DP_SPP_SUPPORT && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
35#include "esp_spp_api.h"
38#ifndef ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR
39#define ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR (0x02)
44 BT_APP_EVT_STACK_UP = 0,
47extern "C" void ccall_i2s_task_handler(
void* arg);
48extern "C" void ccall_audio_data_callback(
const uint8_t* data, uint32_t len);
49extern "C" void ccall_av_hdl_a2d_evt(uint16_t event,
void* p_param);
50extern "C" void ccall_av_hdl_avrc_evt(uint16_t event,
void* p_param);
51#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
52extern "C" void ccall_audio_encoded_callback(esp_a2d_conn_hdl_t conn_hdl,
53 esp_a2d_audio_buff_t* audio_buf);
57enum PinCodeRequest { Undefined, Confirm, Reply };
115#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
116 friend void ccall_audio_encoded_callback(esp_a2d_conn_hdl_t conn_hdl,
117 esp_a2d_audio_buff_t* audio_buf);
129#if A2DP_I2S_AUDIOTOOLS
148#if A2DP_LEGACY_I2S_SUPPORT
150 virtual void set_pin_config(i2s_pin_config_t pin_config) {
151 out->set_pin_config(pin_config);
155 virtual void set_i2s_port(i2s_port_t i2s_num) { out->set_i2s_port(i2s_num); }
158 virtual void set_i2s_config(i2s_config_t i2s_config) {
159 out->set_i2s_config(i2s_config);
164 virtual void set_channels(i2s_channel_t
channels) {
170 virtual void set_bits_per_sample(
int bps) { out->set_bits_per_sample(bps); }
172#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 1)
173 virtual esp_err_t i2s_mclk_pin_select(
const uint8_t pin) {
174 return out->i2s_mclk_pin_select(pin);
195#if A2DP_I2S_AUDIOTOOLS
203 virtual void start(
const char* name,
bool auto_reconect);
206 virtual void start(
const char* name);
210 virtual void end(
bool release_memory =
false);
215#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
220 void (*encoded_cb)(
const uint8_t* data,
size_t len) =
nullptr);
225 this->avrc_connection_state_callback = callback;
231 this->avrc_metadata_callback = callback;
234#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
239 this->avrc_rn_playstatus_callback = callback;
244 void (*callback)(uint32_t play_pos), uint32_t notif_interval = 10) {
245 this->avrc_rn_play_pos_callback = callback;
246 this->notif_interval_s = std::max(notif_interval, (uint32_t)1);
252 void (*callback)(uint8_t*
id)) {
253 this->avrc_rn_track_change_callback = callback;
259 this->sample_rate_callback = callback;
265 bool i2s_output =
true);
278 address_validator = callBack;
304 virtual void pause();
348 avrc_metadata_flags = flags;
357 int count = AUTOCONNECT_TRY_NUM) {
358 reconnect_status =
reconnect ? AutoReconnect : NoReconnect;
359 try_reconnect_max_count = count;
370 if (!rssi_active)
return false;
376 return last_rssi_delta;
381 void (*callback)(esp_bt_gap_cb_param_t::read_rssi_delta_param& rssi)) {
382 rssi_callback = callback;
387 peer_name_callback = callback;
398#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
419#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
423 return esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST,
424 &s_avrc_peer_rn_cap, cmd);
438 volatile bool is_i2s_active =
false;
440 bool is_output =
true;
441 bool is_output_active_by_state =
true;
442 uint16_t m_sample_rate = 44100;
444 uint8_t m_channels = 2;
445 uint32_t m_pkt_cnt = 0;
447 esp_a2d_mct_t audio_type;
448 char pin_code_str[20] = {0};
449 int connection_rety_count = 0;
451 bool spp_active =
false;
452#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
453 esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
455 esp_spp_cfg_t spp_cfg = BT_SPP_DEFAULT_CONFIG();
458 _lock_t s_volume_lock;
459 uint8_t s_volume = 0;
460 bool s_volume_notify;
461 int pin_code_int = 0;
462 PinCodeRequest pin_code_request = Undefined;
463 bool is_pin_code_active =
false;
464 bool avrc_connection_state =
false;
465 int avrc_metadata_flags =
466 ESP_AVRC_MD_ATTR_TITLE | ESP_AVRC_MD_ATTR_ARTIST |
467 ESP_AVRC_MD_ATTR_ALBUM | ESP_AVRC_MD_ATTR_TRACK_NUM |
468 ESP_AVRC_MD_ATTR_NUM_TRACKS | ESP_AVRC_MD_ATTR_GENRE;
469 void (*bt_volumechange)(int) =
nullptr;
470 void (*bt_dis_connected)() =
nullptr;
471 void (*bt_connected)() =
nullptr;
472 void (*data_received)() =
nullptr;
473 void (*stream_reader)(
const uint8_t*, uint32_t) =
nullptr;
474 void (*encoded_stream_reader)(
const uint8_t*, size_t) =
nullptr;
475 void (*raw_stream_reader)(
const uint8_t*, uint32_t) =
nullptr;
476 void (*avrc_connection_state_callback)(
bool connected) =
nullptr;
477 void (*avrc_metadata_callback)(uint8_t,
const uint8_t*) =
nullptr;
478#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
480 void (*avrc_rn_track_change_callback)(uint8_t*) =
nullptr;
481 void (*avrc_rn_play_pos_callback)(uint32_t) =
nullptr;
482 uint32_t notif_interval_s = 10;
484 void (*avrc_rn_volchg_complete_callback)(int) =
nullptr;
485 bool (*address_validator)(
esp_bd_addr_t remote_bda) =
nullptr;
486 void (*sample_rate_callback)(uint16_t rate) =
nullptr;
487 bool swap_left_right =
false;
488 int try_reconnect_max_count = AUTOCONNECT_TRY_NUM;
491 esp_bt_gap_cb_param_t::read_rssi_delta_param last_rssi_delta;
492 bool rssi_active =
false;
493 void (*rssi_callback)(esp_bt_gap_cb_param_t::read_rssi_delta_param& rssi) =
495 void (*peer_name_callback)(
char* peer_name) =
nullptr;
496 int reconnect_delay = 1000;
497 int max_write_size = A2DP_I2S_MAX_WRITE_SIZE;
498 int max_write_delay_ms = A2DP_I2S_MAX_WRITE_DELAY_MS;
500#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
501 esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap = {0};
502 char remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
504#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
505 A2DPCodec desired_codec = A2DP_CODEC_SBC;
509 void app_gap_callback(esp_bt_gap_cb_event_t event,
510 esp_bt_gap_cb_param_t* param)
override;
512 esp_avrc_ct_cb_param_t* param)
override;
514 esp_a2d_cb_param_t* param)
override;
515 void av_hdl_stack_evt(uint16_t event,
void* p_param)
override;
517 virtual int init_bluetooth();
518 virtual bool app_work_dispatch(
app_callback_t p_cback, uint16_t event,
519 void* p_params,
int param_len);
520 virtual void app_alloc_meta_buffer(esp_avrc_ct_cb_param_t* param);
521 virtual void av_new_track();
522 virtual void av_playback_changed();
523 virtual void av_play_pos_changed();
525 virtual void execute_avrc_command(
int cmd);
527 virtual const char* last_bda_nvs_name() {
return "last_bda"; }
529 virtual bool is_reconnect(esp_a2d_disc_rsn_t type) {
530 bool result = is_autoreconnect_allowed &&
531 (reconnect_status == AutoReconnect ||
532 reconnect_status == IsReconnecting) &&
533 has_last_connection();
534 ESP_LOGI(BT_AV_TAG,
"is_reconnect: %s", result ?
"true" :
"false");
544 virtual void av_hdl_a2d_evt(uint16_t event,
void* p_param);
546 virtual void av_hdl_avrc_evt(uint16_t event,
void* p_param);
549 virtual void handle_connection_state(uint16_t event,
void* p_param);
550 virtual void handle_audio_state(uint16_t event,
void* p_param);
551 virtual void handle_audio_cfg(uint16_t event,
void* p_param);
552 virtual void handle_avrc_connection_state(
bool connected);
554#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
558 virtual void volume_set_by_local_host(uint8_t volume);
559 virtual void volume_set_by_controller(uint8_t volume);
560 virtual void av_notify_evt_handler(uint8_t event_id,
561 esp_avrc_rn_param_t* event_parameter);
562 virtual void app_rc_tg_callback(esp_avrc_tg_cb_event_t event,
563 esp_avrc_tg_cb_param_t* param)
override;
564 virtual void av_hdl_avrc_tg_evt(uint16_t event,
void* p_param)
override;
566 virtual void av_notify_evt_handler(uint8_t event_id,
567 uint32_t event_parameter);
570 virtual void init_i2s();
582 virtual void bt_i2s_task_start_up(
void) {}
583 virtual void bt_i2s_task_shut_down(
void) {}
586 return esp_a2d_sink_connect(peer);
588 esp_err_t esp_a2d_disconnect(
esp_bd_addr_t remote_bda)
override {
589 return esp_a2d_sink_disconnect(remote_bda);
592 void set_scan_mode_connectable_default()
override {
596 virtual void set_i2s_active(
bool active);
598 virtual bool isSource() {
return false; }
600 bool is_encoded_output() {
return encoded_stream_reader !=
nullptr; }
void(* app_callback_t)(uint16_t event, void *param)
handler for the dispatched work
Definition BluetoothA2DPCommon.h:133
void set_mono_downmix(bool enabled)
Enables or disables mono downmix.
Definition A2DPVolumeControl.h:118
Common Bluetooth A2DP functions.
Definition BluetoothA2DPCommon.h:182
virtual A2DPVolumeControl * volume_control()
provides access to the VolumeControl object
Definition BluetoothA2DPCommon.h:437
virtual bool reconnect()
Reconnects to the last device.
Definition BluetoothA2DPCommon.cpp:86
virtual void set_scan_mode_connectable(bool connectable)
Defines if the bluetooth is connectable.
Definition BluetoothA2DPCommon.cpp:575
Default Output Class providing both the Legacy I2S and the AudioTools I2S functionality.
Definition BluetoothA2DPOutput.h:203
Abstract Output Class.
Definition BluetoothA2DPOutput.h:22
virtual void set_output(audio_tools::AudioOutput &output)
Not implemented.
Definition BluetoothA2DPOutput.h:32
Output Class using Print API:
Definition BluetoothA2DPOutput.h:126
BluetoothA2DPSink implements a robust, extensible A2DP Bluetooth audio sink for ESP32.
Definition BluetoothA2DPSink.h:106
virtual void set_raw_stream_reader(void(*callBack)(const uint8_t *, uint32_t))
Definition BluetoothA2DPSink.cpp:109
virtual ~BluetoothA2DPSink()
Destructor - stops the playback and releases all resources.
Definition BluetoothA2DPSink.cpp:79
virtual void set_swap_lr_channels(bool swap)
swaps the left and right channel
Definition BluetoothA2DPSink.h:352
void set_output(BluetoothA2DPOutput &output)
Defines the output class: by default we use BluetoothA2DPOutputDefault.
Definition BluetoothA2DPSink.h:181
virtual void activate_pin_code(bool active)
We need to confirm a new seesion by calling confirm_pin_code()
Definition BluetoothA2DPSink.cpp:1263
virtual void next()
AVRC next.
Definition BluetoothA2DPSink.cpp:1225
BluetoothA2DPSink()
Default Constructor: output via callback or Legacy I2S.
Definition BluetoothA2DPSink.cpp:69
virtual void audio_data_callback(const uint8_t *data, uint32_t len)
Definition BluetoothA2DPSink.cpp:1155
virtual const char * get_connected_source_name()
Definition BluetoothA2DPSink.cpp:260
friend void ccall_av_hdl_avrc_evt(uint16_t event, void *p_param)
avrc event handler
Definition BluetoothA2DPSink.cpp:35
virtual void previous()
AVRC previous.
Definition BluetoothA2DPSink.cpp:1228
virtual int pin_code()
provides the requested pin code (0 = undefined)
Definition BluetoothA2DPSink.h:341
virtual void stop()
AVRC stop.
Definition BluetoothA2DPSink.cpp:1223
bool update_rssi()
Requests an update of the rssi delta value.
Definition BluetoothA2DPSink.h:369
void set_max_write_delay_ms(int delay)
defines a small delay after each write: default is 0 ms
Definition BluetoothA2DPSink.h:417
virtual void volume_up()
AVRC increase the volume.
Definition BluetoothA2DPSink.cpp:1238
virtual void fast_forward()
AVRC fast_forward.
Definition BluetoothA2DPSink.cpp:1231
void set_rssi_active(bool active)
Activates the rssi reporting.
Definition BluetoothA2DPSink.h:366
virtual bool is_avrc_connected()
returns true if the avrc service is connected
Definition BluetoothA2DPSink.cpp:1195
virtual void set_stream_reader(void(*callBack)(const uint8_t *, uint32_t), bool i2s_output=true)
Definition BluetoothA2DPSink.cpp:102
virtual void set_volume(uint8_t volume)
Changes the volume.
Definition BluetoothA2DPSink.cpp:1246
virtual uint16_t channels()
Provides the actually set number of channels (1=mono,2=stereo)
Definition BluetoothA2DPSink.h:329
esp_bt_gap_cb_param_t::read_rssi_delta_param get_last_rssi()
provides the last rssi parameters
Definition BluetoothA2DPSink.h:375
virtual void end(bool release_memory=false)
Definition BluetoothA2DPSink.cpp:85
void set_output(audio_tools::AudioOutput &output)
Output AudioOutput using AudioTools library.
Definition BluetoothA2DPSink.h:197
virtual void confirm_pin_code()
confirms the connection request by returning the receivedn pin code
Definition BluetoothA2DPSink.cpp:1267
virtual void set_avrc_rn_play_pos_callback(void(*callback)(uint32_t play_pos), uint32_t notif_interval=10)
Definition BluetoothA2DPSink.h:243
virtual void set_avrc_rn_playstatus_callback(void(*callback)(esp_avrc_playback_stat_t playback))
Definition BluetoothA2DPSink.h:237
virtual void set_mono_downmix(bool enabled)
mix stereo into single mono signal
Definition BluetoothA2DPSink.h:321
BluetoothA2DPSink(audio_tools::AudioStream &output)
Output AudioStream using AudioTools library.
Definition BluetoothA2DPSink.h:135
void set_output(audio_tools::AudioStream &output)
Output AudioStream using AudioTools library.
Definition BluetoothA2DPSink.h:199
void set_output_active(bool flag)
Activate/Deactivate output e.g. to I2S.
Definition BluetoothA2DPSink.h:405
bool is_output_active()
Checks if output is active.
Definition BluetoothA2DPSink.h:411
virtual const char * get_peer_name()
Get the name of the connected source device.
Definition BluetoothA2DPSink.h:430
virtual esp_a2d_mct_t get_audio_type()
Determine the actual audio type.
Definition BluetoothA2DPSink.cpp:218
BluetoothA2DPSink(Print &output)
Output to Arduino Print.
Definition BluetoothA2DPSink.h:142
void app_rc_ct_callback(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) override
callback function for AVRCP controller
Definition BluetoothA2DPSink.cpp:447
bool is_avrc_peer_rn_cap_available()
Returns true if the is_avrc_peer_rn_cap() method can be called.
Definition BluetoothA2DPSink.h:427
virtual void set_avrc_metadata_attribute_mask(int flags)
Definition BluetoothA2DPSink.h:347
virtual esp_bd_addr_t * get_current_peer_address()
Provides the address of the connected device.
Definition BluetoothA2DPSink.h:363
virtual void set_sample_rate_callback(void(*callback)(uint16_t rate))
Defines the method which will be called with the sample rate is updated.
Definition BluetoothA2DPSink.h:258
void set_max_write_size(int size)
defines the max write size: default is A2DP_I2S_MAX_WRITE_SIZE
Definition BluetoothA2DPSink.h:414
virtual uint16_t sample_rate()
Provides the actually set data rate (in samples per second)
Definition BluetoothA2DPSink.h:326
void set_reconnect_delay(int delay)
Definition BluetoothA2DPSink.h:392
BluetoothA2DPOutput * get_output()
Provides access to the output class.
Definition BluetoothA2DPSink.h:184
void set_rssi_callback(void(*callback)(esp_bt_gap_cb_param_t::read_rssi_delta_param &rssi))
Defines the callback that is called when we get an new rssi value.
Definition BluetoothA2DPSink.h:380
void app_a2d_callback(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) override
callback function for A2DP source
Definition BluetoothA2DPSink.cpp:1117
friend void ccall_av_hdl_a2d_evt(uint16_t event, void *p_param)
a2dp event handler
Definition BluetoothA2DPSink.cpp:42
virtual void set_avrc_rn_volumechange_completed(void(*callBack)(int))
Definition BluetoothA2DPSink.cpp:127
BluetoothA2DPSink(audio_tools::AudioOutput &output)
Output AudioOutput using AudioTools library.
Definition BluetoothA2DPSink.h:131
virtual void rewind()
AVRC rewind.
Definition BluetoothA2DPSink.cpp:1234
virtual size_t write_audio(const uint8_t *data, size_t size)
output audio data e.g. to i2s or to queue
Definition BluetoothA2DPSink.h:573
virtual void pause()
AVRC pause.
Definition BluetoothA2DPSink.cpp:1221
virtual void set_avrc_metadata_callback(void(*callback)(uint8_t, const uint8_t *))
Define a callback method which provides the meta data.
Definition BluetoothA2DPSink.h:229
BluetoothA2DPSink(BluetoothA2DPOutput &out)
Define output scenario class.
Definition BluetoothA2DPSink.h:125
virtual void play()
Starts to play music using AVRC.
Definition BluetoothA2DPSink.cpp:1219
size_t i2s_write_data(const uint8_t *data, size_t item_size)
writes the data to i2s
Definition BluetoothA2DPSink.cpp:1296
void set_spp_active(bool flag)
Activates SSP (Serial protocol)
Definition BluetoothA2DPSink.h:396
friend void ccall_audio_data_callback(const uint8_t *data, uint32_t len)
Callback for music stream.
Definition BluetoothA2DPSink.cpp:29
friend void ccall_i2s_task_handler(void *arg)
task hander for i2s
Definition BluetoothA2DPSink.cpp:23
virtual void set_on_volumechange(void(*callBack)(int))
Definition BluetoothA2DPSink.cpp:119
virtual int get_volume()
Determines the volume.
Definition BluetoothA2DPSink.cpp:1258
virtual void set_avrc_rn_volumechange(void(*callBack)(int))
Set the callback that is called when remote changes the volume.
Definition BluetoothA2DPSink.cpp:123
virtual void set_address_validator(bool(*callBack)(esp_bd_addr_t remote_bda))
Allows you to reject unauthorized addresses.
Definition BluetoothA2DPSink.h:276
virtual void set_avrc_rn_track_change_callback(void(*callback)(uint8_t *id))
Definition BluetoothA2DPSink.h:251
virtual void volume_down()
AVRC decrease the volume.
Definition BluetoothA2DPSink.cpp:1242
void set_peer_name_callback(void(*callback)(char *peer_name))
Defines the callback that is called when we get the peer name.
Definition BluetoothA2DPSink.h:386
virtual void set_avrc_connection_state_callback(void(*callback)(bool))
Define a callback method which provides connection state of AVRC service.
Definition BluetoothA2DPSink.h:224
void set_spp_config(esp_spp_cfg_t cfg)
Set SPP configuration (only before start)
Definition BluetoothA2DPSink.h:400
bool set_codec(A2DPCodec codec, void(*encoded_cb)(const uint8_t *data, size_t len)=nullptr)
Definition BluetoothA2DPSink.cpp:222
bool is_avrc_peer_rn_cap(esp_avrc_rn_event_ids_t cmd)
Definition BluetoothA2DPSink.h:422
virtual void set_on_data_received(void(*callBack)())
Define callback which is called when we receive data.
Definition BluetoothA2DPSink.cpp:114
virtual void set_auto_reconnect(bool reconnect, int count=AUTOCONNECT_TRY_NUM)
Definition BluetoothA2DPSink.h:356
virtual void start(const char *name, bool auto_reconect)
starts the I2S bluetooth sink with the inidicated name
Definition BluetoothA2DPSink.cpp:132
void set_output(Print &output)
Output to Arduino Print.
Definition BluetoothA2DPSink.h:188
virtual void i2s_task_handler(void *arg)
dummy functions needed for BluetoothA2DPSinkQueued
Definition BluetoothA2DPSink.h:581
void set_output_active_by_state(bool active)
Automatically deactivates output when state is suspended.
Definition BluetoothA2DPSink.h:408
esp_avrc_rn_event_ids_t
AVRC event notification ids.
Definition external_lists.h:50
esp_avrc_playback_stat_t
AVRCP current status of playback.
Definition external_lists.h:72
uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN]
Bluetooth address.
Definition external_lists.h:107