Arduino A2DP
Loading...
Searching...
No Matches
BluetoothA2DPCommon.h
Go to the documentation of this file.
1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12//
13// Copyright 2020 Phil Schatzmann
14
25#pragma once
26
27#include "config.h"
28#include <stdint.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <stdbool.h>
33#include <string.h>
34#include <math.h>
35#include "freertos/FreeRTOS.h" // needed for ESP Arduino < 2.0
36#include "freertos/timers.h"
37#include "freertos/xtensa_api.h"
38#include "freertos/FreeRTOSConfig.h"
39#include "freertos/queue.h"
40#include "freertos/task.h"
41#include "esp_bt.h"
42#include "esp_bt_main.h"
43#include "esp_bt_device.h"
44#include "esp_gap_bt_api.h"
45#include "esp_a2dp_api.h"
46#include "driver/i2s.h"
47#include "esp_avrc_api.h"
48#include "esp_spp_api.h"
49#include "nvs.h"
50#include "nvs_flash.h"
51#include "SoundData.h"
52#include "A2DPVolumeControl.h"
53#include "esp_task_wdt.h"
54
55#ifdef ARDUINO_ARCH_ESP32
56#include "esp32-hal-log.h"
57#include "esp32-hal-bt.h"
58#else
59#include "esp_log.h"
60
61extern "C" bool btStart();
62extern "C" void delay(long millis);
63extern "C" unsigned long millis();
64
65#endif
66
67// Support for old and new IDF version
68#if !defined(ESP_IDF_4) && !defined(I2S_COMM_FORMAT_STAND_I2S)
69// support for old idf releases
70# define I2S_COMM_FORMAT_STAND_I2S (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB)
71# define I2S_COMM_FORMAT_STAND_MSB (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB)
72# define I2S_COMM_FORMAT_STAND_PCM_LONG (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_LONG)
73# define I2S_COMM_FORMAT_STAND_PCM_SHORT (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_SHORT)
74
75#endif
76
80typedef void (* app_callback_t) (uint16_t event, void *param);
81
83typedef struct {
84 uint16_t sig;
85 uint16_t event;
87 void *param;
88} app_msg_t;
89
90
91#define BT_AV_TAG "BT_AV"
92#define BT_RC_CT_TAG "RCCT"
93#define BT_APP_TAG "BT_API"
94
95/* AVRCP used transaction labels */
96#define APP_RC_CT_TL_GET_CAPS (0)
97#define APP_RC_CT_TL_GET_META_DATA (1)
98#define APP_RC_CT_TL_RN_TRACK_CHANGE (2)
99#define APP_RC_CT_TL_RN_PLAYBACK_CHANGE (3)
100#define APP_RC_CT_TL_RN_PLAY_POS_CHANGE (4)
101
102
103enum ReconnectStatus { NoReconnect, AutoReconnect, IsReconnecting};
104
105
112 public:
114 virtual ~BluetoothA2DPCommon() = default;
115
117 void set_auto_reconnect(bool active);
118
120 virtual void disconnect();
121
123 virtual bool reconnect();
124
126 virtual bool connect_to(esp_bd_addr_t peer);
127
129 virtual void set_connected(bool active);
130
132 virtual void end(bool releaseMemory=false);
133
135 virtual bool is_connected() = 0;
136
138 virtual void set_volume(uint8_t volume){
139 ESP_LOGI(BT_AV_TAG, "set_volume: %d", volume);
140 volume_value = volume;
141 volume_control()->set_volume(volume);
142 volume_control()->set_enabled(true);
143 is_volume_used = true;
144 }
145
147 virtual int get_volume(){
148 return is_volume_used ? volume_value : 0;
149 }
150
153 volume_control_ptr = ptr;
154 }
155
157 virtual esp_a2d_audio_state_t get_audio_state();
158
160 virtual esp_a2d_connection_state_t get_connection_state();
161
164 virtual void set_on_connection_state_changed(void (*callBack)(esp_a2d_connection_state_t state, void *), void *obj=nullptr);
165
168 virtual void set_on_audio_state_changed_post(void (*callBack)(esp_a2d_audio_state_t state, void*), void* obj=nullptr);
169
171 virtual void set_on_audio_state_changed(void (*callBack)(esp_a2d_audio_state_t state, void*), void* obj=nullptr);
172
174 virtual void debounce(void(*cb)(void),int ms);
175
177 void log_free_heap();
178
180 const char* to_str(esp_a2d_connection_state_t state);
181
183 const char* to_str(esp_a2d_audio_state_t state);
184
186 const char* to_str(esp_bd_addr_t bda);
187
189 const char* to_str(esp_avrc_playback_stat_t state);
190
192 void set_task_priority(UBaseType_t priority){
193 task_priority = priority;
194 }
195
196
198 void set_task_core(BaseType_t core){
199 task_core = core;
200 }
201
203 void set_event_queue_size(int size){
204 event_queue_size = size;
205 }
206
208 void set_event_stack_size(int size){
209 event_stack_size = size;
210 }
211
213 virtual esp_bd_addr_t* get_last_peer_address() {
214 return &last_connection;
215 }
216
217#ifdef ESP_IDF_4
219 virtual void set_discoverability(esp_bt_discovery_mode_t d);
220#endif
221
223 virtual void set_connectable(bool connectable) {
224 set_scan_mode_connectable(connectable);
225 }
226
228 virtual const char* get_name() {
229 return bt_name;
230 }
231
233 virtual void clean_last_connection();
234
235 protected:
236 const char* bt_name = {0};
237 esp_bd_addr_t peer_bd_addr;
238 ReconnectStatus reconnect_status = AutoReconnect;
239 unsigned long reconnect_timout=0;
240 unsigned int default_reconnect_timout=10000;
241 bool is_autoreconnect_allowed = false;
242 uint32_t debounce_ms = 0;
243 A2DPDefaultVolumeControl default_volume_control;
244 A2DPVolumeControl *volume_control_ptr = nullptr;
245 esp_bd_addr_t last_connection = {0,0,0,0,0,0};
246 bool is_start_disabled = false;
247 void (*connection_state_callback)(esp_a2d_connection_state_t state, void* obj) = nullptr;
248 void (*audio_state_callback)(esp_a2d_audio_state_t state, void* obj) = nullptr;
249 void (*audio_state_callback_post)(esp_a2d_audio_state_t state, void* obj) = nullptr;
250 void *connection_state_obj = nullptr;
251 void *audio_state_obj = nullptr;
252 void *audio_state_obj_post = nullptr;
253 const char *m_a2d_conn_state_str[4] = {"Disconnected", "Connecting", "Connected", "Disconnecting"};
254 const char *m_a2d_audio_state_str[3] = {"Suspended", "Stopped", "Started"};
255 const char *m_avrc_playback_state_str[5] = {"stopped", "playing", "paused", "forward seek", "reverse seek"};
256 esp_a2d_audio_state_t audio_state = ESP_A2D_AUDIO_STATE_STOPPED;
257 esp_a2d_connection_state_t connection_state = ESP_A2D_CONNECTION_STATE_DISCONNECTED;
258 UBaseType_t task_priority = configMAX_PRIORITIES - 10;
259 // volume
260 uint8_t volume_value = 0;
261 bool is_volume_used = false;
262 BaseType_t task_core = 1;
263
264 int event_queue_size = 20;
265 int event_stack_size = 3072;
266
267
268#ifdef ESP_IDF_4
269 esp_bt_discovery_mode_t discoverability = ESP_BT_GENERAL_DISCOVERABLE;
270#endif
271
272 virtual esp_err_t esp_a2d_connect(esp_bd_addr_t peer) = 0;
273 virtual const char* last_bda_nvs_name() = 0;
274 virtual void get_last_connection();
275 virtual void set_last_connection(esp_bd_addr_t bda);
276 virtual bool has_last_connection();
277 // change the scan mode
278 virtual void set_scan_mode_connectable(bool connectable);
279
282 return volume_control_ptr !=nullptr ? volume_control_ptr : &default_volume_control;
283 }
284};
285
void delay(long millis)
call vTaskDelay to deley for the indicated number of milliseconds
Definition: BluetoothA2DPCommon.cpp:354
bool btStart()
Startup logic as implemented by Arduino - This is not available if we use this library outside of Ard...
Definition: BluetoothA2DPCommon.cpp:328
void(* app_callback_t)(uint16_t event, void *param)
handler for the dispatched work
Definition: BluetoothA2DPCommon.h:80
Default implementation for handling of the volume of the audio data.
Definition: A2DPVolumeControl.h:88
Abstract class for handling of the volume of the audio data.
Definition: A2DPVolumeControl.h:28
Common Bluetooth A2DP functions.
Definition: BluetoothA2DPCommon.h:111
void set_event_stack_size(int size)
Defines the stack size of the event task (in bytes)
Definition: BluetoothA2DPCommon.h:208
virtual void set_connected(bool active)
Calls disconnect or reconnect.
Definition: BluetoothA2DPCommon.cpp:56
virtual void set_volume(uint8_t volume)
Sets the volume (range 0 - 255)
Definition: BluetoothA2DPCommon.h:138
virtual int get_volume()
Determines the actual volume.
Definition: BluetoothA2DPCommon.h:147
virtual bool is_connected()=0
Checks if A2DP is connected.
virtual void set_on_audio_state_changed_post(void(*callBack)(esp_a2d_audio_state_t state, void *), void *obj=nullptr)
Definition: BluetoothA2DPCommon.cpp:230
const char * to_str(esp_a2d_connection_state_t state)
converts esp_a2d_connection_state_t to a string
Definition: BluetoothA2DPCommon.cpp:251
virtual const char * get_name()
Provides the actual SSID name.
Definition: BluetoothA2DPCommon.h:228
virtual ~BluetoothA2DPCommon()=default
Destructor.
virtual esp_a2d_connection_state_t get_connection_state()
Determine the connection state.
Definition: BluetoothA2DPCommon.cpp:22
void set_auto_reconnect(bool active)
activate / deactivate the automatic reconnection to the last address (per default this is on)
Definition: BluetoothA2DPCommon.cpp:28
virtual void set_on_audio_state_changed(void(*callBack)(esp_a2d_audio_state_t state, void *), void *obj=nullptr)
Set the callback that is called when the audio state is changed.
Definition: BluetoothA2DPCommon.cpp:223
void set_task_priority(UBaseType_t priority)
defines the task priority (the default value is configMAX_PRIORITIES - 10)
Definition: BluetoothA2DPCommon.h:192
void set_task_core(BaseType_t core)
Defines the core which is used to start the tasks (to process the events and audio queue)
Definition: BluetoothA2DPCommon.h:198
virtual esp_a2d_audio_state_t get_audio_state()
Determine the actual audio state.
Definition: BluetoothA2DPCommon.cpp:18
virtual void end(bool releaseMemory=false)
Closes the connection and stops A2DP.
Definition: BluetoothA2DPCommon.cpp:80
virtual void set_volume_control(A2DPVolumeControl *ptr)
you can define a custom VolumeControl implementation
Definition: BluetoothA2DPCommon.h:152
virtual bool connect_to(esp_bd_addr_t peer)
Connnects to the indicated address.
Definition: BluetoothA2DPCommon.cpp:44
void log_free_heap()
Logs the free heap.
Definition: BluetoothA2DPCommon.cpp:246
virtual void set_connectable(bool connectable)
Bluetooth connectable.
Definition: BluetoothA2DPCommon.h:223
virtual void set_discoverability(esp_bt_discovery_mode_t d)
Bluetooth discoverability.
Definition: BluetoothA2DPCommon.cpp:279
virtual A2DPVolumeControl * volume_control()
provides access to the VolumeControl object
Definition: BluetoothA2DPCommon.h:281
virtual void clean_last_connection()
clean last connection (delete)
Definition: BluetoothA2DPCommon.cpp:208
virtual void debounce(void(*cb)(void), int ms)
Prevents that the same method is executed multiple times within the indicated time limit.
Definition: BluetoothA2DPCommon.cpp:237
virtual void set_on_connection_state_changed(void(*callBack)(esp_a2d_connection_state_t state, void *), void *obj=nullptr)
Set the callback that is called when the connection state is changed.
Definition: BluetoothA2DPCommon.cpp:216
virtual void disconnect()
Closes the connection.
Definition: BluetoothA2DPCommon.cpp:66
virtual bool reconnect()
Reconnects to the last device.
Definition: BluetoothA2DPCommon.cpp:33
virtual esp_bd_addr_t * get_last_peer_address()
Provides the address of the last device.
Definition: BluetoothA2DPCommon.h:213
void set_event_queue_size(int size)
Defines the queue size of the event task.
Definition: BluetoothA2DPCommon.h:203
virtual void set_scan_mode_connectable(bool connectable)
Defines if the bluetooth is connectable.
Definition: BluetoothA2DPCommon.cpp:288
Internal message to be sent for BluetoothA2DPSink and BluetoothA2DPSource.
Definition: BluetoothA2DPCommon.h:83
app_callback_t cb
Definition: BluetoothA2DPCommon.h:86
uint16_t event
Definition: BluetoothA2DPCommon.h:85
uint16_t sig
Definition: BluetoothA2DPCommon.h:84
void * param
Definition: BluetoothA2DPCommon.h:87