1 /*
2 * Copyright (C) 2023 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37
38 #define BTSTACK_FILE__ "a2dp_sink_demo.c"
39
40 /*
41 * a2dp_sink_demo.c
42 */
43
44 // *****************************************************************************
45 /* EXAMPLE_START(a2dp_sink_demo): A2DP Sink - Receive Audio Stream and Control Playback
46 *
47 * @text This A2DP Sink example demonstrates how to use the A2DP Sink service to
48 * receive an audio data stream from a remote A2DP Source device. In addition,
49 * the AVRCP Controller is used to get information on currently played media,
50 * such are title, artist and album, as well as to control the playback,
51 * i.e. to play, stop, repeat, etc. If HAVE_BTSTACK_STDIN is set, press SPACE on
52 * the console to show the available AVDTP and AVRCP commands.
53 *
54 * @text To test with a remote device, e.g. a mobile phone,
55 * pair from the remote device with the demo, then start playing music on the remote device.
56 * Alternatively, set the device_addr_string to the Bluetooth address of your
57 * remote device in the code, and call connect from the UI.
58 *
59 * @text For more info on BTstack audio, see our blog post
60 * [A2DP Sink and Source on STM32 F4 Discovery Board](http://bluekitchen-gmbh.com/a2dp-sink-and-source-on-stm32-f4-discovery-board/).
61 *
62 */
63 // *****************************************************************************
64
65 #include <inttypes.h>
66 #include <stdint.h>
67 #include <stdio.h>
68 #include <string.h>
69
70 #include "btstack.h"
71
72 #include "btstack_resample.h"
73
74 //#define AVRCP_BROWSING_ENABLED
75
76 #ifdef HAVE_BTSTACK_STDIN
77 #include "btstack_stdin.h"
78 #endif
79
80 #ifdef HAVE_BTSTACK_AUDIO_EFFECTIVE_SAMPLERATE
81 #include "btstack_sample_rate_compensation.h"
82 #endif
83
84 #include "btstack_ring_buffer.h"
85
86 #ifdef HAVE_POSIX_FILE_IO
87 #include "wav_util.h"
88 #define STORE_TO_WAV_FILE
89 #ifdef _MSC_VER
90 // ignore deprecated warning for fopen
91 #pragma warning(disable : 4996)
92 #endif
93 #endif
94
95 #define NUM_CHANNELS 2
96 #define BYTES_PER_FRAME (2*NUM_CHANNELS)
97 #define MAX_SBC_FRAME_SIZE 120
98
99 #ifdef HAVE_BTSTACK_STDIN
100 static const char * device_addr_string = "00:1B:DC:08:E2:72"; // pts v5.0
101 static bd_addr_t device_addr;
102 #endif
103
104 #ifdef HAVE_BTSTACK_AUDIO_EFFECTIVE_SAMPLERATE
105 static btstack_sample_rate_compensation_t sample_rate_compensation;
106 #endif
107
108 static btstack_packet_callback_registration_t hci_event_callback_registration;
109
110 static uint8_t sdp_avdtp_sink_service_buffer[150];
111 static uint8_t sdp_avrcp_target_service_buffer[150];
112 static uint8_t sdp_avrcp_controller_service_buffer[200];
113 static uint8_t device_id_sdp_service_buffer[100];
114
115 // we support all configurations with bitpool 2-53
116 static uint8_t media_sbc_codec_capabilities[] = {
117 0xFF,//(AVDTP_SBC_44100 << 4) | AVDTP_SBC_STEREO,
118 0xFF,//(AVDTP_SBC_BLOCK_LENGTH_16 << 4) | (AVDTP_SBC_SUBBANDS_8 << 2) | AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS,
119 2, 53
120 };
121
122 // WAV File
123 #ifdef STORE_TO_WAV_FILE
124 static uint32_t audio_frame_count = 0;
125 static char * wav_filename = "a2dp_sink_demo.wav";
126 #endif
127
128 // SBC Decoder for WAV file or live playback
129 static const btstack_sbc_decoder_t * sbc_decoder_instance;
130 static btstack_sbc_decoder_bluedroid_t sbc_decoder_context;
131
132 // ring buffer for SBC Frames
133 // below 30: add samples, 30-40: fine, above 40: drop samples
134 #define OPTIMAL_FRAMES_MIN 60
135 #define OPTIMAL_FRAMES_MAX 80
136 #define ADDITIONAL_FRAMES 30
137 static uint8_t sbc_frame_storage[(OPTIMAL_FRAMES_MAX + ADDITIONAL_FRAMES) * MAX_SBC_FRAME_SIZE];
138 static btstack_ring_buffer_t sbc_frame_ring_buffer;
139 static unsigned int sbc_frame_size;
140
141 // overflow buffer for not fully used sbc frames, with additional frames for resampling
142 static uint8_t decoded_audio_storage[(128+16) * BYTES_PER_FRAME];
143 static btstack_ring_buffer_t decoded_audio_ring_buffer;
144
145 static int media_initialized = 0;
146 static int audio_stream_started;
147 #ifdef HAVE_BTSTACK_AUDIO_EFFECTIVE_SAMPLERATE
148 static int l2cap_stream_started;
149 #endif
150 static btstack_resample_t resample_instance;
151
152 // temp storage of lower-layer request for audio samples
153 static int16_t * request_buffer;
154 static int request_frames;
155
156 // sink state
157 static int volume_percentage = 0;
158 static avrcp_battery_status_t battery_status = AVRCP_BATTERY_STATUS_WARNING;
159
160 #ifdef ENABLE_AVRCP_COVER_ART
161 static char a2dp_sink_demo_image_handle[8];
162 static avrcp_cover_art_client_t a2dp_sink_demo_cover_art_client;
163 static bool a2dp_sink_demo_cover_art_client_connected;
164 static uint16_t a2dp_sink_demo_cover_art_cid;
165 static uint8_t a2dp_sink_demo_ertm_buffer[2000];
166 static l2cap_ertm_config_t a2dp_sink_demo_ertm_config = {
167 1, // ertm mandatory
168 2, // max transmit, some tests require > 1
169 2000,
170 12000,
171 512, // l2cap ertm mtu
172 2,
173 2,
174 1, // 16-bit FCS
175 };
176 static bool a2dp_sink_cover_art_download_active;
177 static uint32_t a2dp_sink_cover_art_file_size;
178 #ifdef HAVE_POSIX_FILE_IO
179 static const char * a2dp_sink_demo_thumbnail_path = "cover.jpg";
180 static FILE * a2dp_sink_cover_art_file;
181 #endif
182 #endif
183
184 typedef struct {
185 uint8_t reconfigure;
186 uint8_t num_channels;
187 uint16_t sampling_frequency;
188 uint8_t block_length;
189 uint8_t subbands;
190 uint8_t min_bitpool_value;
191 uint8_t max_bitpool_value;
192 btstack_sbc_channel_mode_t channel_mode;
193 btstack_sbc_allocation_method_t allocation_method;
194 } media_codec_configuration_sbc_t;
195
196 typedef enum {
197 STREAM_STATE_CLOSED,
198 STREAM_STATE_OPEN,
199 STREAM_STATE_PLAYING,
200 STREAM_STATE_PAUSED,
201 } stream_state_t;
202
203 typedef struct {
204 uint8_t a2dp_local_seid;
205 uint8_t media_sbc_codec_configuration[4];
206 } a2dp_sink_demo_stream_endpoint_t;
207 static a2dp_sink_demo_stream_endpoint_t a2dp_sink_demo_stream_endpoint;
208
209 typedef struct {
210 bd_addr_t addr;
211 uint16_t a2dp_cid;
212 uint8_t a2dp_local_seid;
213 stream_state_t stream_state;
214 media_codec_configuration_sbc_t sbc_configuration;
215 } a2dp_sink_demo_a2dp_connection_t;
216 static a2dp_sink_demo_a2dp_connection_t a2dp_sink_demo_a2dp_connection;
217
218 typedef struct {
219 bd_addr_t addr;
220 uint16_t avrcp_cid;
221 bool playing;
222 uint16_t notifications_supported_by_target;
223 } a2dp_sink_demo_avrcp_connection_t;
224 static a2dp_sink_demo_avrcp_connection_t a2dp_sink_demo_avrcp_connection;
225
226 /* @section Main Application Setup
227 *
228 * @text The Listing MainConfiguration shows how to set up AD2P Sink and AVRCP services.
229 * Besides calling init() method for each service, you'll also need to register several packet handlers:
230 * - hci_packet_handler - handles legacy pairing, here by using fixed '0000' pin code.
231 * - a2dp_sink_packet_handler - handles events on stream connection status (established, released), the media codec configuration, and, the status of the stream itself (opened, paused, stopped).
232 * - handle_l2cap_media_data_packet - used to receive streaming data. If STORE_TO_WAV_FILE directive (check btstack_config.h) is used, the SBC decoder will be used to decode the SBC data into PCM frames. The resulting PCM frames are then processed in the SBC Decoder callback.
233 * - avrcp_packet_handler - receives AVRCP connect/disconnect event.
234 * - avrcp_controller_packet_handler - receives answers for sent AVRCP commands.
235 * - avrcp_target_packet_handler - receives AVRCP commands, and registered notifications.
236 * - stdin_process - used to trigger AVRCP commands to the A2DP Source device, such are get now playing info, start, stop, volume control. Requires HAVE_BTSTACK_STDIN.
237 *
238 * @text To announce A2DP Sink and AVRCP services, you need to create corresponding
239 * SDP records and register them with the SDP service.
240 *
241 * @text Note, currently only the SBC codec is supported.
242 * If you want to store the audio data in a file, you'll need to define STORE_TO_WAV_FILE.
243 * If STORE_TO_WAV_FILE directive is defined, the SBC decoder needs to get initialized when a2dp_sink_packet_handler receives event A2DP_SUBEVENT_STREAM_STARTED.
244 * The initialization of the SBC decoder requires a callback that handles PCM data:
245 * - handle_pcm_data - handles PCM audio frames. Here, they are stored in a wav file if STORE_TO_WAV_FILE is defined, and/or played using the audio library.
246 */
247
248 /* LISTING_START(MainConfiguration): Setup Audio Sink and AVRCP services */
249 static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
250 static void a2dp_sink_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t event_size);
251 static void handle_l2cap_media_data_packet(uint8_t seid, uint8_t *packet, uint16_t size);
252 static void avrcp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
253 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
254 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
255 #ifdef HAVE_BTSTACK_STDIN
256 static void stdin_process(char cmd);
257 #endif
258
setup_demo(void)259 static int setup_demo(void){
260
261 // init protocols
262 l2cap_init();
263 sdp_init();
264 #ifdef ENABLE_BLE
265 // Initialize LE Security Manager. Needed for cross-transport key derivation
266 sm_init();
267 #endif
268 #ifdef ENABLE_AVRCP_COVER_ART
269 goep_client_init();
270 avrcp_cover_art_client_init();
271 #endif
272
273 // Init profiles
274 a2dp_sink_init();
275 avrcp_init();
276 avrcp_controller_init();
277 avrcp_target_init();
278
279
280 // Configure A2DP Sink
281 a2dp_sink_register_packet_handler(&a2dp_sink_packet_handler);
282 a2dp_sink_register_media_handler(&handle_l2cap_media_data_packet);
283 a2dp_sink_demo_stream_endpoint_t * stream_endpoint = &a2dp_sink_demo_stream_endpoint;
284 avdtp_stream_endpoint_t * local_stream_endpoint = a2dp_sink_create_stream_endpoint(AVDTP_AUDIO,
285 AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities),
286 stream_endpoint->media_sbc_codec_configuration, sizeof(stream_endpoint->media_sbc_codec_configuration));
287 btstack_assert(local_stream_endpoint != NULL);
288 // - Store stream enpoint's SEP ID, as it is used by A2DP API to identify the stream endpoint
289 stream_endpoint->a2dp_local_seid = avdtp_local_seid(local_stream_endpoint);
290
291
292 // Configure AVRCP Controller + Target
293 avrcp_register_packet_handler(&avrcp_packet_handler);
294 avrcp_controller_register_packet_handler(&avrcp_controller_packet_handler);
295 avrcp_target_register_packet_handler(&avrcp_target_packet_handler);
296
297
298 // Configure SDP
299
300 // - Create and register A2DP Sink service record
301 memset(sdp_avdtp_sink_service_buffer, 0, sizeof(sdp_avdtp_sink_service_buffer));
302 a2dp_sink_create_sdp_record(sdp_avdtp_sink_service_buffer, sdp_create_service_record_handle(),
303 AVDTP_SINK_FEATURE_MASK_HEADPHONE, NULL, NULL);
304 btstack_assert(de_get_len( sdp_avdtp_sink_service_buffer) <= sizeof(sdp_avdtp_sink_service_buffer));
305 sdp_register_service(sdp_avdtp_sink_service_buffer);
306
307 // - Create AVRCP Controller service record and register it with SDP. We send Category 1 commands to the media player, e.g. play/pause
308 memset(sdp_avrcp_controller_service_buffer, 0, sizeof(sdp_avrcp_controller_service_buffer));
309 uint16_t controller_supported_features = 1 << AVRCP_CONTROLLER_SUPPORTED_FEATURE_CATEGORY_PLAYER_OR_RECORDER;
310 #ifdef AVRCP_BROWSING_ENABLED
311 controller_supported_features |= 1 << AVRCP_CONTROLLER_SUPPORTED_FEATURE_BROWSING;
312 #endif
313 #ifdef ENABLE_AVRCP_COVER_ART
314 controller_supported_features |= 1 << AVRCP_CONTROLLER_SUPPORTED_FEATURE_COVER_ART_GET_LINKED_THUMBNAIL;
315 #endif
316 avrcp_controller_create_sdp_record(sdp_avrcp_controller_service_buffer, sdp_create_service_record_handle(),
317 controller_supported_features, NULL, NULL);
318 btstack_assert(de_get_len( sdp_avrcp_controller_service_buffer) <= sizeof(sdp_avrcp_controller_service_buffer));
319 sdp_register_service(sdp_avrcp_controller_service_buffer);
320
321 // - Create and register A2DP Sink service record
322 // - We receive Category 2 commands from the media player, e.g. volume up/down
323 memset(sdp_avrcp_target_service_buffer, 0, sizeof(sdp_avrcp_target_service_buffer));
324 uint16_t target_supported_features = 1 << AVRCP_TARGET_SUPPORTED_FEATURE_CATEGORY_MONITOR_OR_AMPLIFIER;
325 avrcp_target_create_sdp_record(sdp_avrcp_target_service_buffer,
326 sdp_create_service_record_handle(), target_supported_features, NULL, NULL);
327 btstack_assert(de_get_len( sdp_avrcp_target_service_buffer) <= sizeof(sdp_avrcp_target_service_buffer));
328 sdp_register_service(sdp_avrcp_target_service_buffer);
329
330 // - Create and register Device ID (PnP) service record
331 memset(device_id_sdp_service_buffer, 0, sizeof(device_id_sdp_service_buffer));
332 device_id_create_sdp_record(device_id_sdp_service_buffer,
333 sdp_create_service_record_handle(), DEVICE_ID_VENDOR_ID_SOURCE_BLUETOOTH, BLUETOOTH_COMPANY_ID_BLUEKITCHEN_GMBH, 1, 1);
334 btstack_assert(de_get_len( device_id_sdp_service_buffer) <= sizeof(device_id_sdp_service_buffer));
335 sdp_register_service(device_id_sdp_service_buffer);
336
337
338 // Configure GAP - discovery / connection
339
340 // - Set local name with a template Bluetooth address, that will be automatically
341 // replaced with an actual address once it is available, i.e. when BTstack boots
342 // up and starts talking to a Bluetooth module.
343 gap_set_local_name("A2DP Sink Demo 00:00:00:00:00:00");
344
345 // - Allow to show up in Bluetooth inquiry
346 gap_discoverable_control(1);
347
348 // - Set Class of Device - Service Class: Audio, Major Device Class: Audio, Minor: Headphone
349 gap_set_class_of_device(0x200404);
350
351 // - Allow for role switch in general and sniff mode
352 gap_set_default_link_policy_settings( LM_LINK_POLICY_ENABLE_ROLE_SWITCH | LM_LINK_POLICY_ENABLE_SNIFF_MODE );
353
354 // - Allow for role switch on outgoing connections
355 // - This allows A2DP Source, e.g. smartphone, to become master when we re-connect to it.
356 gap_set_allow_role_switch(true);
357
358
359 // Register for HCI events
360 hci_event_callback_registration.callback = &hci_packet_handler;
361 hci_add_event_handler(&hci_event_callback_registration);
362
363 // Inform about audio playback / test options
364 #ifdef HAVE_POSIX_FILE_IO
365 if (!btstack_audio_sink_get_instance()){
366 printf("No audio playback.\n");
367 } else {
368 printf("Audio playback supported.\n");
369 }
370 #ifdef STORE_TO_WAV_FILE
371 printf("Audio will be stored to \'%s\' file.\n", wav_filename);
372 #endif
373 #endif
374 return 0;
375 }
376 /* LISTING_END */
377
378
playback_handler(int16_t * buffer,uint16_t num_audio_frames)379 static void playback_handler(int16_t * buffer, uint16_t num_audio_frames){
380
381 #ifdef STORE_TO_WAV_FILE
382 int wav_samples = num_audio_frames * NUM_CHANNELS;
383 int16_t * wav_buffer = buffer;
384 #endif
385
386 // called from lower-layer but guaranteed to be on main thread
387 if (sbc_frame_size == 0){
388 memset(buffer, 0, num_audio_frames * BYTES_PER_FRAME);
389 return;
390 }
391
392 // first fill from resampled audio
393 uint32_t bytes_read;
394 btstack_ring_buffer_read(&decoded_audio_ring_buffer, (uint8_t *) buffer, num_audio_frames * BYTES_PER_FRAME, &bytes_read);
395 buffer += bytes_read / NUM_CHANNELS;
396 num_audio_frames -= bytes_read / BYTES_PER_FRAME;
397
398 // then start decoding sbc frames using request_* globals
399 request_buffer = buffer;
400 request_frames = num_audio_frames;
401 while (request_frames && btstack_ring_buffer_bytes_available(&sbc_frame_ring_buffer) >= sbc_frame_size){
402 // decode frame
403 uint8_t sbc_frame[MAX_SBC_FRAME_SIZE];
404 btstack_ring_buffer_read(&sbc_frame_ring_buffer, sbc_frame, sbc_frame_size, &bytes_read);
405 sbc_decoder_instance->decode_signed_16(&sbc_decoder_context, 0, sbc_frame, sbc_frame_size);
406 }
407
408 #ifdef STORE_TO_WAV_FILE
409 audio_frame_count += num_audio_frames;
410 wav_writer_write_int16(wav_samples, wav_buffer);
411 #endif
412 }
413
handle_pcm_data(int16_t * data,int num_audio_frames,int num_channels,int sample_rate,void * context)414 static void handle_pcm_data(int16_t * data, int num_audio_frames, int num_channels, int sample_rate, void * context){
415 UNUSED(sample_rate);
416 UNUSED(context);
417 UNUSED(num_channels); // must be stereo == 2
418
419 const btstack_audio_sink_t * audio_sink = btstack_audio_sink_get_instance();
420 if (!audio_sink){
421 #ifdef STORE_TO_WAV_FILE
422 audio_frame_count += num_audio_frames;
423 wav_writer_write_int16(num_audio_frames * NUM_CHANNELS, data);
424 #endif
425 return;
426 }
427
428 // resample into request buffer - add some additional space for resampling
429 int16_t output_buffer[(128+16) * NUM_CHANNELS]; // 16 * 8 * 2
430 uint32_t resampled_frames = btstack_resample_block(&resample_instance, data, num_audio_frames, output_buffer);
431
432 // store data in btstack_audio buffer first
433 int frames_to_copy = btstack_min(resampled_frames, request_frames);
434 memcpy(request_buffer, output_buffer, frames_to_copy * BYTES_PER_FRAME);
435 request_frames -= frames_to_copy;
436 request_buffer += frames_to_copy * NUM_CHANNELS;
437
438 // and rest in ring buffer
439 int frames_to_store = resampled_frames - frames_to_copy;
440 if (frames_to_store){
441 int status = btstack_ring_buffer_write(&decoded_audio_ring_buffer, (uint8_t *)&output_buffer[frames_to_copy * NUM_CHANNELS], frames_to_store * BYTES_PER_FRAME);
442 if (status){
443 printf("Error storing samples in PCM ring buffer!!!\n");
444 }
445 }
446 }
447
media_processing_init(media_codec_configuration_sbc_t * configuration)448 static int media_processing_init(media_codec_configuration_sbc_t * configuration){
449 if (media_initialized) return 0;
450 sbc_decoder_instance = btstack_sbc_decoder_bluedroid_init_instance(&sbc_decoder_context);
451 sbc_decoder_instance->configure(&sbc_decoder_context, SBC_MODE_STANDARD, handle_pcm_data, NULL);
452
453 #ifdef STORE_TO_WAV_FILE
454 wav_writer_open(wav_filename, configuration->num_channels, configuration->sampling_frequency);
455 #endif
456
457 btstack_ring_buffer_init(&sbc_frame_ring_buffer, sbc_frame_storage, sizeof(sbc_frame_storage));
458 btstack_ring_buffer_init(&decoded_audio_ring_buffer, decoded_audio_storage, sizeof(decoded_audio_storage));
459 btstack_resample_init(&resample_instance, configuration->num_channels);
460
461 // setup audio playback
462 const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
463 if (audio){
464 audio->init(NUM_CHANNELS, configuration->sampling_frequency, &playback_handler);
465 }
466
467 audio_stream_started = 0;
468 media_initialized = 1;
469 return 0;
470 }
471
media_processing_start(void)472 static void media_processing_start(void){
473 if (!media_initialized) return;
474
475 #ifdef HAVE_BTSTACK_AUDIO_EFFECTIVE_SAMPLERATE
476 btstack_sample_rate_compensation_reset( &sample_rate_compensation, btstack_run_loop_get_time_ms() );
477 #endif
478 // setup audio playback
479 const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
480 if (audio){
481 audio->start_stream();
482 }
483 audio_stream_started = 1;
484 }
485
media_processing_pause(void)486 static void media_processing_pause(void){
487 if (!media_initialized) return;
488
489 // stop audio playback
490 audio_stream_started = 0;
491 #ifdef HAVE_BTSTACK_AUDIO_EFFECTIVE_SAMPLERATE
492 l2cap_stream_started = 0;
493 #endif
494
495 const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
496 if (audio){
497 audio->stop_stream();
498 }
499 // discard pending data
500 btstack_ring_buffer_reset(&decoded_audio_ring_buffer);
501 btstack_ring_buffer_reset(&sbc_frame_ring_buffer);
502 }
503
media_processing_close(void)504 static void media_processing_close(void){
505 if (!media_initialized) return;
506
507 media_initialized = 0;
508 audio_stream_started = 0;
509 sbc_frame_size = 0;
510 #ifdef HAVE_BTSTACK_AUDIO_EFFECTIVE_SAMPLERATE
511 l2cap_stream_started = 0;
512 #endif
513
514 #ifdef STORE_TO_WAV_FILE
515 wav_writer_close();
516 uint32_t total_frames_nr = sbc_decoder_context.good_frames_nr + sbc_decoder_context.bad_frames_nr + sbc_decoder_context.zero_frames_nr;
517
518 printf("WAV Writer: Decoding done. Processed %u SBC frames:\n - %d good\n - %d bad\n", total_frames_nr, sbc_decoder_context.good_frames_nr, total_frames_nr - sbc_decoder_context.good_frames_nr);
519 printf("WAV Writer: Wrote %u audio frames to wav file: %s\n", audio_frame_count, wav_filename);
520 #endif
521
522 // stop audio playback
523 const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
524 if (audio){
525 printf("close stream\n");
526 audio->close();
527 }
528 }
529
530 /* @section Handle Media Data Packet
531 *
532 * @text Here the audio data, are received through the handle_l2cap_media_data_packet callback.
533 * Currently, only the SBC media codec is supported. Hence, the media data consists of the media packet header and the SBC packet.
534 * The SBC frame will be stored in a ring buffer for later processing (instead of decoding it to PCM right away which would require a much larger buffer).
535 * If the audio stream wasn't started already and there are enough SBC frames in the ring buffer, start playback.
536 */
537
538 static int read_media_data_header(uint8_t * packet, int size, int * offset, avdtp_media_packet_header_t * media_header);
539 static int read_sbc_header(uint8_t * packet, int size, int * offset, avdtp_sbc_codec_header_t * sbc_header);
540
handle_l2cap_media_data_packet(uint8_t seid,uint8_t * packet,uint16_t size)541 static void handle_l2cap_media_data_packet(uint8_t seid, uint8_t *packet, uint16_t size){
542 UNUSED(seid);
543 int pos = 0;
544
545 avdtp_media_packet_header_t media_header;
546 if (!read_media_data_header(packet, size, &pos, &media_header)) return;
547
548 avdtp_sbc_codec_header_t sbc_header;
549 if (!read_sbc_header(packet, size, &pos, &sbc_header)) return;
550
551 int packet_length = size-pos;
552 uint8_t *packet_begin = packet+pos;
553
554 const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
555 // process data right away if there's no audio implementation active, e.g. on posix systems to store as .wav
556 if (!audio){
557 sbc_decoder_instance->decode_signed_16(&sbc_decoder_context, 0, packet_begin, packet_length);
558 return;
559 }
560
561 // store sbc frame size for buffer management
562 sbc_frame_size = packet_length / sbc_header.num_frames;
563 int status = btstack_ring_buffer_write(&sbc_frame_ring_buffer, packet_begin, packet_length);
564 if (status != ERROR_CODE_SUCCESS){
565 printf("Error storing samples in SBC ring buffer!!!\n");
566 }
567
568 // decide on audio sync drift based on number of sbc frames in queue
569 int sbc_frames_in_buffer = btstack_ring_buffer_bytes_available(&sbc_frame_ring_buffer) / sbc_frame_size;
570 #ifdef HAVE_BTSTACK_AUDIO_EFFECTIVE_SAMPLERATE
571 if( !l2cap_stream_started && audio_stream_started ) {
572 l2cap_stream_started = 1;
573 btstack_sample_rate_compensation_init( &sample_rate_compensation, btstack_run_loop_get_time_ms(), a2dp_sink_demo_a2dp_connection.sbc_configuration.sampling_frequency, FLOAT_TO_Q15(1.f) );
574 }
575 // update sample rate compensation
576 if( audio_stream_started && (audio != NULL)) {
577 uint32_t resampling_factor = btstack_sample_rate_compensation_update( &sample_rate_compensation, btstack_run_loop_get_time_ms(), sbc_header.num_frames*128, audio->get_samplerate() );
578 btstack_resample_set_factor(&resample_instance, resampling_factor);
579 // printf("sbc buffer level : %"PRIu32"\n", btstack_ring_buffer_bytes_available(&sbc_frame_ring_buffer));
580 }
581 #else
582 uint32_t resampling_factor;
583
584 // nominal factor (fixed-point 2^16) and compensation offset
585 uint32_t nominal_factor = 0x10000;
586 uint32_t compensation = 0x00100;
587
588 if (sbc_frames_in_buffer < OPTIMAL_FRAMES_MIN){
589 resampling_factor = nominal_factor - compensation; // stretch samples
590 } else if (sbc_frames_in_buffer <= OPTIMAL_FRAMES_MAX){
591 resampling_factor = nominal_factor; // nothing to do
592 } else {
593 resampling_factor = nominal_factor + compensation; // compress samples
594 }
595
596 btstack_resample_set_factor(&resample_instance, resampling_factor);
597 #endif
598 // start stream if enough frames buffered
599 if (!audio_stream_started && sbc_frames_in_buffer >= OPTIMAL_FRAMES_MIN){
600 media_processing_start();
601 }
602 }
603
read_sbc_header(uint8_t * packet,int size,int * offset,avdtp_sbc_codec_header_t * sbc_header)604 static int read_sbc_header(uint8_t * packet, int size, int * offset, avdtp_sbc_codec_header_t * sbc_header){
605 int sbc_header_len = 12; // without crc
606 int pos = *offset;
607
608 if (size - pos < sbc_header_len){
609 printf("Not enough data to read SBC header, expected %d, received %d\n", sbc_header_len, size-pos);
610 return 0;
611 }
612
613 sbc_header->fragmentation = get_bit16(packet[pos], 7);
614 sbc_header->starting_packet = get_bit16(packet[pos], 6);
615 sbc_header->last_packet = get_bit16(packet[pos], 5);
616 sbc_header->num_frames = packet[pos] & 0x0f;
617 pos++;
618 *offset = pos;
619 return 1;
620 }
621
read_media_data_header(uint8_t * packet,int size,int * offset,avdtp_media_packet_header_t * media_header)622 static int read_media_data_header(uint8_t *packet, int size, int *offset, avdtp_media_packet_header_t *media_header){
623 int media_header_len = 12; // without crc
624 int pos = *offset;
625
626 if (size - pos < media_header_len){
627 printf("Not enough data to read media packet header, expected %d, received %d\n", media_header_len, size-pos);
628 return 0;
629 }
630
631 media_header->version = packet[pos] & 0x03;
632 media_header->padding = get_bit16(packet[pos],2);
633 media_header->extension = get_bit16(packet[pos],3);
634 media_header->csrc_count = (packet[pos] >> 4) & 0x0F;
635 pos++;
636
637 media_header->marker = get_bit16(packet[pos],0);
638 media_header->payload_type = (packet[pos] >> 1) & 0x7F;
639 pos++;
640
641 media_header->sequence_number = big_endian_read_16(packet, pos);
642 pos+=2;
643
644 media_header->timestamp = big_endian_read_32(packet, pos);
645 pos+=4;
646
647 media_header->synchronization_source = big_endian_read_32(packet, pos);
648 pos+=4;
649 *offset = pos;
650 return 1;
651 }
652
dump_sbc_configuration(media_codec_configuration_sbc_t * configuration)653 static void dump_sbc_configuration(media_codec_configuration_sbc_t * configuration){
654 printf(" - num_channels: %d\n", configuration->num_channels);
655 printf(" - sampling_frequency: %d\n", configuration->sampling_frequency);
656 printf(" - channel_mode: %d\n", configuration->channel_mode);
657 printf(" - block_length: %d\n", configuration->block_length);
658 printf(" - subbands: %d\n", configuration->subbands);
659 printf(" - allocation_method: %d\n", configuration->allocation_method);
660 printf(" - bitpool_value [%d, %d] \n", configuration->min_bitpool_value, configuration->max_bitpool_value);
661 printf("\n");
662 }
663
hci_packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)664 static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
665 UNUSED(channel);
666 UNUSED(size);
667 if (packet_type != HCI_EVENT_PACKET) return;
668 if (hci_event_packet_get_type(packet) == HCI_EVENT_PIN_CODE_REQUEST) {
669 bd_addr_t address;
670 printf("Pin code request - using '0000'\n");
671 hci_event_pin_code_request_get_bd_addr(packet, address);
672 gap_pin_code_response(address, "0000");
673 }
674 }
675
676 #ifdef ENABLE_AVRCP_COVER_ART
a2dp_sink_demo_cover_art_packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)677 static void a2dp_sink_demo_cover_art_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
678 UNUSED(channel);
679 UNUSED(size);
680 uint8_t status;
681 uint16_t cid;
682 switch (packet_type){
683 case BIP_DATA_PACKET:
684 if (a2dp_sink_cover_art_download_active){
685 a2dp_sink_cover_art_file_size += size;
686 #ifdef HAVE_POSIX_FILE_IO
687 fwrite(packet, 1, size, a2dp_sink_cover_art_file);
688 #else
689 printf("Cover art : TODO - store %u bytes image data\n", size);
690 #endif
691 } else {
692 uint16_t i;
693 for (i=0;i<size;i++){
694 putchar(packet[i]);
695 }
696 printf("\n");
697 }
698 break;
699 case HCI_EVENT_PACKET:
700 switch (hci_event_packet_get_type(packet)){
701 case HCI_EVENT_AVRCP_META:
702 switch (hci_event_avrcp_meta_get_subevent_code(packet)){
703 case AVRCP_SUBEVENT_COVER_ART_CONNECTION_ESTABLISHED:
704 status = avrcp_subevent_cover_art_connection_established_get_status(packet);
705 cid = avrcp_subevent_cover_art_connection_established_get_cover_art_cid(packet);
706 if (status == ERROR_CODE_SUCCESS){
707 printf("Cover Art : connection established, cover art cid 0x%02x\n", cid);
708 a2dp_sink_demo_cover_art_client_connected = true;
709 } else {
710 printf("Cover Art : connection failed, status 0x%02x\n", status);
711 a2dp_sink_demo_cover_art_cid = 0;
712 }
713 break;
714 case AVRCP_SUBEVENT_COVER_ART_OPERATION_COMPLETE:
715 if (a2dp_sink_cover_art_download_active){
716 a2dp_sink_cover_art_download_active = false;
717 #ifdef HAVE_POSIX_FILE_IO
718 printf("Cover Art : download of '%s complete, size %u bytes'\n",
719 a2dp_sink_demo_thumbnail_path, a2dp_sink_cover_art_file_size);
720 fclose(a2dp_sink_cover_art_file);
721 a2dp_sink_cover_art_file = NULL;
722 #else
723 printf("Cover Art: download completed\n");
724 #endif
725 }
726 break;
727 case AVRCP_SUBEVENT_COVER_ART_CONNECTION_RELEASED:
728 a2dp_sink_demo_cover_art_client_connected = false;
729 a2dp_sink_demo_cover_art_cid = 0;
730 printf("Cover Art : connection released 0x%02x\n",
731 avrcp_subevent_cover_art_connection_released_get_cover_art_cid(packet));
732 break;
733 default:
734 break;
735 }
736 break;
737 default:
738 break;
739 }
740 break;
741 default:
742 break;
743 }
744 }
745
a2dp_sink_demo_cover_art_connect(void)746 static uint8_t a2dp_sink_demo_cover_art_connect(void) {
747 uint8_t status;
748 status = avrcp_cover_art_client_connect(&a2dp_sink_demo_cover_art_client, a2dp_sink_demo_cover_art_packet_handler,
749 device_addr, a2dp_sink_demo_ertm_buffer,
750 sizeof(a2dp_sink_demo_ertm_buffer), &a2dp_sink_demo_ertm_config,
751 &a2dp_sink_demo_cover_art_cid);
752 return status;
753 }
754 #endif
755
avrcp_packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)756 static void avrcp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
757 UNUSED(channel);
758 UNUSED(size);
759 uint16_t local_cid;
760 uint8_t status;
761 bd_addr_t address;
762
763 a2dp_sink_demo_avrcp_connection_t * connection = &a2dp_sink_demo_avrcp_connection;
764
765 if (packet_type != HCI_EVENT_PACKET) return;
766 if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
767 switch (packet[2]){
768 case AVRCP_SUBEVENT_CONNECTION_ESTABLISHED: {
769 local_cid = avrcp_subevent_connection_established_get_avrcp_cid(packet);
770 status = avrcp_subevent_connection_established_get_status(packet);
771 if (status != ERROR_CODE_SUCCESS){
772 printf("AVRCP: Connection failed, status 0x%02x\n", status);
773 connection->avrcp_cid = 0;
774 return;
775 }
776
777 connection->avrcp_cid = local_cid;
778 avrcp_subevent_connection_established_get_bd_addr(packet, address);
779 printf("AVRCP: Connected to %s, cid 0x%02x\n", bd_addr_to_str(address), connection->avrcp_cid);
780
781 #ifdef HAVE_BTSTACK_STDIN
782 // use address for outgoing connections
783 avrcp_subevent_connection_established_get_bd_addr(packet, device_addr);
784 #endif
785
786 avrcp_target_support_event(connection->avrcp_cid, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED);
787 avrcp_target_support_event(connection->avrcp_cid, AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED);
788 avrcp_target_battery_status_changed(connection->avrcp_cid, battery_status);
789
790 // query supported events:
791 avrcp_controller_get_supported_events(connection->avrcp_cid);
792 return;
793 }
794
795 case AVRCP_SUBEVENT_CONNECTION_RELEASED:
796 printf("AVRCP: Channel released: cid 0x%02x\n", avrcp_subevent_connection_released_get_avrcp_cid(packet));
797 connection->avrcp_cid = 0;
798 connection->notifications_supported_by_target = 0;
799 return;
800 default:
801 break;
802 }
803 }
804
avrcp_controller_packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)805 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
806 UNUSED(channel);
807 UNUSED(size);
808
809 // helper to print c strings
810 uint8_t avrcp_subevent_value[256];
811 uint8_t play_status;
812 uint8_t event_id;
813
814 a2dp_sink_demo_avrcp_connection_t * avrcp_connection = &a2dp_sink_demo_avrcp_connection;
815
816 if (packet_type != HCI_EVENT_PACKET) return;
817 if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
818 if (avrcp_connection->avrcp_cid == 0) return;
819
820 memset(avrcp_subevent_value, 0, sizeof(avrcp_subevent_value));
821 switch (packet[2]){
822 case AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID:
823 avrcp_connection->notifications_supported_by_target |= (1 << avrcp_subevent_get_capability_event_id_get_event_id(packet));
824 break;
825 case AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID_DONE:
826
827 printf("AVRCP Controller: supported notifications by target:\n");
828 for (event_id = (uint8_t) AVRCP_NOTIFICATION_EVENT_FIRST_INDEX; event_id < (uint8_t) AVRCP_NOTIFICATION_EVENT_LAST_INDEX; event_id++){
829 printf(" - [%s] %s\n",
830 (avrcp_connection->notifications_supported_by_target & (1 << event_id)) != 0 ? "X" : " ",
831 avrcp_notification2str((avrcp_notification_event_id_t)event_id));
832 }
833 printf("\n\n");
834
835 // automatically enable notifications
836 avrcp_controller_enable_notification(avrcp_connection->avrcp_cid, AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED);
837 avrcp_controller_enable_notification(avrcp_connection->avrcp_cid, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED);
838 avrcp_controller_enable_notification(avrcp_connection->avrcp_cid, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED);
839
840 #ifdef ENABLE_AVRCP_COVER_ART
841 // image handles become invalid on player change, registe for notifications
842 avrcp_controller_enable_notification(a2dp_sink_demo_avrcp_connection.avrcp_cid, AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED);
843 // trigger cover art client connection
844 a2dp_sink_demo_cover_art_connect();
845 #endif
846 break;
847
848 case AVRCP_SUBEVENT_NOTIFICATION_STATE:
849 event_id = (avrcp_notification_event_id_t)avrcp_subevent_notification_state_get_event_id(packet);
850 printf("AVRCP Controller: %s notification registered\n", avrcp_notification2str(event_id));
851 break;
852
853 case AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_POS_CHANGED:
854 printf("AVRCP Controller: Playback position changed, position %d ms\n", (unsigned int) avrcp_subevent_notification_playback_pos_changed_get_playback_position_ms(packet));
855 break;
856 case AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED:
857 printf("AVRCP Controller: Playback status changed %s\n", avrcp_play_status2str(avrcp_subevent_notification_playback_status_changed_get_play_status(packet)));
858 play_status = avrcp_subevent_notification_playback_status_changed_get_play_status(packet);
859 switch (play_status){
860 case AVRCP_PLAYBACK_STATUS_PLAYING:
861 avrcp_connection->playing = true;
862 break;
863 default:
864 avrcp_connection->playing = false;
865 break;
866 }
867 break;
868
869 case AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED:
870 printf("AVRCP Controller: Playing content changed\n");
871 break;
872
873 case AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED:
874 printf("AVRCP Controller: Track changed\n");
875 break;
876
877 case AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED:
878 printf("AVRCP Controller: Available Players Changed\n");
879 break;
880
881 case AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE:{
882 uint8_t shuffle_mode = avrcp_subevent_shuffle_and_repeat_mode_get_shuffle_mode(packet);
883 uint8_t repeat_mode = avrcp_subevent_shuffle_and_repeat_mode_get_repeat_mode(packet);
884 printf("AVRCP Controller: %s, %s\n", avrcp_shuffle2str(shuffle_mode), avrcp_repeat2str(repeat_mode));
885 break;
886 }
887 case AVRCP_SUBEVENT_NOW_PLAYING_TRACK_INFO:
888 printf("AVRCP Controller: Track %d\n", avrcp_subevent_now_playing_track_info_get_track(packet));
889 break;
890
891 case AVRCP_SUBEVENT_NOW_PLAYING_TOTAL_TRACKS_INFO:
892 printf("AVRCP Controller: Total Tracks %d\n", avrcp_subevent_now_playing_total_tracks_info_get_total_tracks(packet));
893 break;
894
895 case AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO:
896 if (avrcp_subevent_now_playing_title_info_get_value_len(packet) > 0){
897 memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_title_info_get_value(packet), avrcp_subevent_now_playing_title_info_get_value_len(packet));
898 printf("AVRCP Controller: Title %s\n", avrcp_subevent_value);
899 }
900 break;
901
902 case AVRCP_SUBEVENT_NOW_PLAYING_ARTIST_INFO:
903 if (avrcp_subevent_now_playing_artist_info_get_value_len(packet) > 0){
904 memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_artist_info_get_value(packet), avrcp_subevent_now_playing_artist_info_get_value_len(packet));
905 printf("AVRCP Controller: Artist %s\n", avrcp_subevent_value);
906 }
907 break;
908
909 case AVRCP_SUBEVENT_NOW_PLAYING_ALBUM_INFO:
910 if (avrcp_subevent_now_playing_album_info_get_value_len(packet) > 0){
911 memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_album_info_get_value(packet), avrcp_subevent_now_playing_album_info_get_value_len(packet));
912 printf("AVRCP Controller: Album %s\n", avrcp_subevent_value);
913 }
914 break;
915
916 case AVRCP_SUBEVENT_NOW_PLAYING_GENRE_INFO:
917 if (avrcp_subevent_now_playing_genre_info_get_value_len(packet) > 0){
918 memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_genre_info_get_value(packet), avrcp_subevent_now_playing_genre_info_get_value_len(packet));
919 printf("AVRCP Controller: Genre %s\n", avrcp_subevent_value);
920 }
921 break;
922
923 case AVRCP_SUBEVENT_PLAY_STATUS:
924 printf("AVRCP Controller: Song length %"PRIu32" ms, Song position %"PRIu32" ms, Play status %s\n",
925 avrcp_subevent_play_status_get_song_length(packet),
926 avrcp_subevent_play_status_get_song_position(packet),
927 avrcp_play_status2str(avrcp_subevent_play_status_get_play_status(packet)));
928 break;
929
930 case AVRCP_SUBEVENT_OPERATION_COMPLETE:
931 printf("AVRCP Controller: %s complete\n", avrcp_operation2str(avrcp_subevent_operation_complete_get_operation_id(packet)));
932 break;
933
934 case AVRCP_SUBEVENT_OPERATION_START:
935 printf("AVRCP Controller: %s start\n", avrcp_operation2str(avrcp_subevent_operation_start_get_operation_id(packet)));
936 break;
937
938 case AVRCP_SUBEVENT_NOTIFICATION_EVENT_TRACK_REACHED_END:
939 printf("AVRCP Controller: Track reached end\n");
940 break;
941
942 case AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE:
943 printf("AVRCP Controller: Set Player App Value %s\n", avrcp_ctype2str(avrcp_subevent_player_application_value_response_get_command_type(packet)));
944 break;
945
946 #ifdef ENABLE_AVRCP_COVER_ART
947 case AVRCP_SUBEVENT_NOTIFICATION_EVENT_UIDS_CHANGED:
948 if (a2dp_sink_demo_cover_art_client_connected){
949 printf("AVRCP Controller: UIDs changed -> disconnect cover art client\n");
950 avrcp_cover_art_client_disconnect(a2dp_sink_demo_cover_art_cid);
951 }
952 break;
953
954 case AVRCP_SUBEVENT_NOW_PLAYING_COVER_ART_INFO:
955 if (avrcp_subevent_now_playing_cover_art_info_get_value_len(packet) == 7){
956 memcpy(a2dp_sink_demo_image_handle, avrcp_subevent_now_playing_cover_art_info_get_value(packet), 7);
957 printf("AVRCP Controller: Cover Art %s\n", a2dp_sink_demo_image_handle);
958 }
959 break;
960 #endif
961
962 default:
963 break;
964 }
965 }
966
avrcp_volume_changed(uint8_t volume)967 static void avrcp_volume_changed(uint8_t volume){
968 const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
969 if (audio){
970 audio->set_volume(volume);
971 }
972 }
973
avrcp_target_packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)974 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
975 UNUSED(channel);
976 UNUSED(size);
977
978 if (packet_type != HCI_EVENT_PACKET) return;
979 if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
980
981 uint8_t volume;
982 char const * button_state;
983 avrcp_operation_id_t operation_id;
984
985 switch (packet[2]){
986 case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:
987 volume = avrcp_subevent_notification_volume_changed_get_absolute_volume(packet);
988 volume_percentage = volume * 100 / 127;
989 printf("AVRCP Target : Volume set to %d%% (%d)\n", volume_percentage, volume);
990 avrcp_volume_changed(volume);
991 break;
992
993 case AVRCP_SUBEVENT_OPERATION:
994 operation_id = (avrcp_operation_id_t) avrcp_subevent_operation_get_operation_id(packet);
995 button_state = avrcp_subevent_operation_get_button_pressed(packet) > 0 ? "PRESS" : "RELEASE";
996 switch (operation_id){
997 case AVRCP_OPERATION_ID_VOLUME_UP:
998 printf("AVRCP Target : VOLUME UP (%s)\n", button_state);
999 break;
1000 case AVRCP_OPERATION_ID_VOLUME_DOWN:
1001 printf("AVRCP Target : VOLUME DOWN (%s)\n", button_state);
1002 break;
1003 default:
1004 return;
1005 }
1006 break;
1007 default:
1008 printf("AVRCP Target : Event 0x%02x is not parsed\n", packet[2]);
1009 break;
1010 }
1011 }
1012
a2dp_sink_packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)1013 static void a2dp_sink_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1014 UNUSED(channel);
1015 UNUSED(size);
1016 uint8_t status;
1017
1018 uint8_t allocation_method;
1019
1020 if (packet_type != HCI_EVENT_PACKET) return;
1021 if (hci_event_packet_get_type(packet) != HCI_EVENT_A2DP_META) return;
1022
1023 a2dp_sink_demo_a2dp_connection_t * a2dp_conn = &a2dp_sink_demo_a2dp_connection;
1024
1025 switch (packet[2]){
1026 case A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION:
1027 printf("A2DP Sink : Received non SBC codec - not implemented\n");
1028 break;
1029 case A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
1030 printf("A2DP Sink : Received SBC codec configuration\n");
1031 a2dp_conn->sbc_configuration.reconfigure = a2dp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
1032 a2dp_conn->sbc_configuration.num_channels = a2dp_subevent_signaling_media_codec_sbc_configuration_get_num_channels(packet);
1033 a2dp_conn->sbc_configuration.sampling_frequency = a2dp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
1034 a2dp_conn->sbc_configuration.block_length = a2dp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
1035 a2dp_conn->sbc_configuration.subbands = a2dp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
1036 a2dp_conn->sbc_configuration.min_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_min_bitpool_value(packet);
1037 a2dp_conn->sbc_configuration.max_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet);
1038
1039 allocation_method = a2dp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
1040
1041 // Adapt Bluetooth spec definition to SBC Encoder expected input
1042 a2dp_conn->sbc_configuration.allocation_method = (btstack_sbc_allocation_method_t)(allocation_method - 1);
1043
1044 switch (a2dp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet)){
1045 case AVDTP_CHANNEL_MODE_JOINT_STEREO:
1046 a2dp_conn->sbc_configuration.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
1047 break;
1048 case AVDTP_CHANNEL_MODE_STEREO:
1049 a2dp_conn->sbc_configuration.channel_mode = SBC_CHANNEL_MODE_STEREO;
1050 break;
1051 case AVDTP_CHANNEL_MODE_DUAL_CHANNEL:
1052 a2dp_conn->sbc_configuration.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
1053 break;
1054 case AVDTP_CHANNEL_MODE_MONO:
1055 a2dp_conn->sbc_configuration.channel_mode = SBC_CHANNEL_MODE_MONO;
1056 break;
1057 default:
1058 btstack_assert(false);
1059 break;
1060 }
1061 dump_sbc_configuration(&a2dp_conn->sbc_configuration);
1062 break;
1063 }
1064
1065 case A2DP_SUBEVENT_STREAM_ESTABLISHED:
1066 status = a2dp_subevent_stream_established_get_status(packet);
1067 if (status != ERROR_CODE_SUCCESS){
1068 printf("A2DP Sink : Streaming connection failed, status 0x%02x\n", status);
1069 break;
1070 }
1071
1072 a2dp_subevent_stream_established_get_bd_addr(packet, a2dp_conn->addr);
1073 a2dp_conn->a2dp_cid = a2dp_subevent_stream_established_get_a2dp_cid(packet);
1074 a2dp_conn->a2dp_local_seid = a2dp_subevent_stream_established_get_local_seid(packet);
1075 a2dp_conn->stream_state = STREAM_STATE_OPEN;
1076
1077 printf("A2DP Sink : Streaming connection is established, address %s, cid 0x%02x, local seid %d\n",
1078 bd_addr_to_str(a2dp_conn->addr), a2dp_conn->a2dp_cid, a2dp_conn->a2dp_local_seid);
1079 #ifdef HAVE_BTSTACK_STDIN
1080 // use address for outgoing connections
1081 memcpy(device_addr, a2dp_conn->addr, 6);
1082 #endif
1083 break;
1084
1085 #ifdef ENABLE_AVDTP_ACCEPTOR_EXPLICIT_START_STREAM_CONFIRMATION
1086 case A2DP_SUBEVENT_START_STREAM_REQUESTED:
1087 printf("A2DP Sink : Explicit Accept to start stream, local_seid %d\n", a2dp_subevent_start_stream_requested_get_local_seid(packet));
1088 a2dp_sink_start_stream_accept(a2dp_cid, a2dp_local_seid);
1089 break;
1090 #endif
1091 case A2DP_SUBEVENT_STREAM_STARTED:
1092 printf("A2DP Sink : Stream started\n");
1093 a2dp_conn->stream_state = STREAM_STATE_PLAYING;
1094 if (a2dp_conn->sbc_configuration.reconfigure){
1095 media_processing_close();
1096 }
1097 // prepare media processing
1098 media_processing_init(&a2dp_conn->sbc_configuration);
1099 // audio stream is started when buffer reaches minimal level
1100 break;
1101
1102 case A2DP_SUBEVENT_STREAM_SUSPENDED:
1103 printf("A2DP Sink : Stream paused\n");
1104 a2dp_conn->stream_state = STREAM_STATE_PAUSED;
1105 media_processing_pause();
1106 break;
1107
1108 case A2DP_SUBEVENT_STREAM_RELEASED:
1109 printf("A2DP Sink : Stream released\n");
1110 a2dp_conn->stream_state = STREAM_STATE_CLOSED;
1111 media_processing_close();
1112 break;
1113
1114 case A2DP_SUBEVENT_SIGNALING_CONNECTION_RELEASED:
1115 printf("A2DP Sink : Signaling connection released\n");
1116 a2dp_conn->a2dp_cid = 0;
1117 media_processing_close();
1118 break;
1119
1120 default:
1121 break;
1122 }
1123 }
1124
1125 #ifdef HAVE_BTSTACK_STDIN
show_usage(void)1126 static void show_usage(void){
1127 bd_addr_t iut_address;
1128 gap_local_bd_addr(iut_address);
1129 printf("\n--- A2DP Sink Demo Console %s ---\n", bd_addr_to_str(iut_address));
1130 printf("b - A2DP Sink create connection to addr %s\n", bd_addr_to_str(device_addr));
1131 printf("B - A2DP Sink disconnect\n");
1132
1133 printf("\n--- AVRCP Controller ---\n");
1134 printf("c - AVRCP create connection to addr %s\n", bd_addr_to_str(device_addr));
1135 printf("C - AVRCP disconnect\n");
1136 printf("O - get play status\n");
1137 printf("j - get now playing info\n");
1138 printf("k - play\n");
1139 printf("K - stop\n");
1140 printf("L - pause\n");
1141 printf("u - start fast forward\n");
1142 printf("U - stop fast forward\n");
1143 printf("n - start rewind\n");
1144 printf("N - stop rewind\n");
1145 printf("i - forward\n");
1146 printf("I - backward\n");
1147 printf("M - mute\n");
1148 printf("r - skip\n");
1149 printf("q - query repeat and shuffle mode\n");
1150 printf("v - repeat single track\n");
1151 printf("w - delay report\n");
1152 printf("x - repeat all tracks\n");
1153 printf("X - disable repeat mode\n");
1154 printf("z - shuffle all tracks\n");
1155 printf("Z - disable shuffle mode\n");
1156
1157 printf("a/A - register/deregister TRACK_CHANGED\n");
1158 printf("R/P - register/deregister PLAYBACK_POS_CHANGED\n");
1159
1160 printf("s/S - send/release long button press REWIND\n");
1161
1162 printf("\n--- Volume and Battery Control ---\n");
1163 printf("t - volume up for 10 percent\n");
1164 printf("T - volume down for 10 percent\n");
1165 printf("V - toggle Battery status from AVRCP_BATTERY_STATUS_NORMAL to AVRCP_BATTERY_STATUS_FULL_CHARGE\n");
1166
1167 #ifdef ENABLE_AVRCP_COVER_ART
1168 printf("\n--- Cover Art Client ---\n");
1169 printf("d - connect to addr %s\n", bd_addr_to_str(device_addr));
1170 printf("D - disconnect\n");
1171 if (a2dp_sink_demo_cover_art_client_connected == false){
1172 if (a2dp_sink_demo_avrcp_connection.avrcp_cid == 0){
1173 printf("Not connected, press 'b' or 'c' to first connect AVRCP, then press 'd' to connect cover art client\n");
1174 } else {
1175 printf("Not connected, press 'd' to connect cover art client\n");
1176 }
1177 } else if (a2dp_sink_demo_image_handle[0] == 0){
1178 printf("No image handle, use 'j' to get current track info\n");
1179 }
1180 printf("---\n");
1181 #endif
1182
1183 }
1184 #endif
1185
1186 #ifdef HAVE_BTSTACK_STDIN
1187
stdin_process(char cmd)1188 static void stdin_process(char cmd){
1189 uint8_t status = ERROR_CODE_SUCCESS;
1190 uint8_t volume;
1191 avrcp_battery_status_t old_battery_status;
1192
1193 a2dp_sink_demo_a2dp_connection_t * a2dp_connection = &a2dp_sink_demo_a2dp_connection;
1194 a2dp_sink_demo_avrcp_connection_t * avrcp_connection = &a2dp_sink_demo_avrcp_connection;
1195
1196 switch (cmd){
1197 case 'b':
1198 status = a2dp_sink_establish_stream(device_addr, &a2dp_connection->a2dp_cid);
1199 printf(" - Create AVDTP connection to addr %s, and local seid %d, cid 0x%02x.\n",
1200 bd_addr_to_str(device_addr), a2dp_connection->a2dp_local_seid, a2dp_connection->a2dp_cid);
1201 break;
1202 case 'B':
1203 printf(" - AVDTP disconnect from addr %s.\n", bd_addr_to_str(device_addr));
1204 a2dp_sink_disconnect(a2dp_connection->a2dp_cid);
1205 break;
1206 case 'c':
1207 printf(" - Create AVRCP connection to addr %s.\n", bd_addr_to_str(device_addr));
1208 status = avrcp_connect(device_addr, &avrcp_connection->avrcp_cid);
1209 break;
1210 case 'C':
1211 printf(" - AVRCP disconnect from addr %s.\n", bd_addr_to_str(device_addr));
1212 status = avrcp_disconnect(avrcp_connection->avrcp_cid);
1213 break;
1214
1215 case '\n':
1216 case '\r':
1217 break;
1218 case 'w':
1219 printf("Send delay report\n");
1220 avdtp_sink_delay_report(a2dp_connection->a2dp_cid, a2dp_connection->a2dp_local_seid, 100);
1221 break;
1222 // Volume Control
1223 case 't':
1224 volume_percentage = volume_percentage <= 90 ? volume_percentage + 10 : 100;
1225 volume = volume_percentage * 127 / 100;
1226 printf(" - volume up for 10 percent, %d%% (%d) \n", volume_percentage, volume);
1227 status = avrcp_target_volume_changed(avrcp_connection->avrcp_cid, volume);
1228 avrcp_volume_changed(volume);
1229 break;
1230 case 'T':
1231 volume_percentage = volume_percentage >= 10 ? volume_percentage - 10 : 0;
1232 volume = volume_percentage * 127 / 100;
1233 printf(" - volume down for 10 percent, %d%% (%d) \n", volume_percentage, volume);
1234 status = avrcp_target_volume_changed(avrcp_connection->avrcp_cid, volume);
1235 avrcp_volume_changed(volume);
1236 break;
1237 case 'V':
1238 old_battery_status = battery_status;
1239
1240 if (battery_status < AVRCP_BATTERY_STATUS_FULL_CHARGE){
1241 battery_status = (avrcp_battery_status_t)((uint8_t) battery_status + 1);
1242 } else {
1243 battery_status = AVRCP_BATTERY_STATUS_NORMAL;
1244 }
1245 printf(" - toggle battery value, old %d, new %d\n", old_battery_status, battery_status);
1246 status = avrcp_target_battery_status_changed(avrcp_connection->avrcp_cid, battery_status);
1247 break;
1248 case 'O':
1249 printf(" - get play status\n");
1250 status = avrcp_controller_get_play_status(avrcp_connection->avrcp_cid);
1251 break;
1252 case 'j':
1253 printf(" - get now playing info\n");
1254 status = avrcp_controller_get_now_playing_info(avrcp_connection->avrcp_cid);
1255 break;
1256 case 'k':
1257 printf(" - play\n");
1258 status = avrcp_controller_play(avrcp_connection->avrcp_cid);
1259 break;
1260 case 'K':
1261 printf(" - stop\n");
1262 status = avrcp_controller_stop(avrcp_connection->avrcp_cid);
1263 break;
1264 case 'L':
1265 printf(" - pause\n");
1266 status = avrcp_controller_pause(avrcp_connection->avrcp_cid);
1267 break;
1268 case 'u':
1269 printf(" - start fast forward\n");
1270 status = avrcp_controller_press_and_hold_fast_forward(avrcp_connection->avrcp_cid);
1271 break;
1272 case 'U':
1273 printf(" - stop fast forward\n");
1274 status = avrcp_controller_release_press_and_hold_cmd(avrcp_connection->avrcp_cid);
1275 break;
1276 case 'n':
1277 printf(" - start rewind\n");
1278 status = avrcp_controller_press_and_hold_rewind(avrcp_connection->avrcp_cid);
1279 break;
1280 case 'N':
1281 printf(" - stop rewind\n");
1282 status = avrcp_controller_release_press_and_hold_cmd(avrcp_connection->avrcp_cid);
1283 break;
1284 case 'i':
1285 printf(" - forward\n");
1286 status = avrcp_controller_forward(avrcp_connection->avrcp_cid);
1287 break;
1288 case 'I':
1289 printf(" - backward\n");
1290 status = avrcp_controller_backward(avrcp_connection->avrcp_cid);
1291 break;
1292 case 'M':
1293 printf(" - mute\n");
1294 status = avrcp_controller_mute(avrcp_connection->avrcp_cid);
1295 break;
1296 case 'r':
1297 printf(" - skip\n");
1298 status = avrcp_controller_skip(avrcp_connection->avrcp_cid);
1299 break;
1300 case 'q':
1301 printf(" - query repeat and shuffle mode\n");
1302 status = avrcp_controller_query_shuffle_and_repeat_modes(avrcp_connection->avrcp_cid);
1303 break;
1304 case 'v':
1305 printf(" - repeat single track\n");
1306 status = avrcp_controller_set_repeat_mode(avrcp_connection->avrcp_cid, AVRCP_REPEAT_MODE_SINGLE_TRACK);
1307 break;
1308 case 'x':
1309 printf(" - repeat all tracks\n");
1310 status = avrcp_controller_set_repeat_mode(avrcp_connection->avrcp_cid, AVRCP_REPEAT_MODE_ALL_TRACKS);
1311 break;
1312 case 'X':
1313 printf(" - disable repeat mode\n");
1314 status = avrcp_controller_set_repeat_mode(avrcp_connection->avrcp_cid, AVRCP_REPEAT_MODE_OFF);
1315 break;
1316 case 'z':
1317 printf(" - shuffle all tracks\n");
1318 status = avrcp_controller_set_shuffle_mode(avrcp_connection->avrcp_cid, AVRCP_SHUFFLE_MODE_ALL_TRACKS);
1319 break;
1320 case 'Z':
1321 printf(" - disable shuffle mode\n");
1322 status = avrcp_controller_set_shuffle_mode(avrcp_connection->avrcp_cid, AVRCP_SHUFFLE_MODE_OFF);
1323 break;
1324 case 'a':
1325 printf("AVRCP: enable notification TRACK_CHANGED\n");
1326 status = avrcp_controller_enable_notification(avrcp_connection->avrcp_cid, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED);
1327 break;
1328 case 'A':
1329 printf("AVRCP: disable notification TRACK_CHANGED\n");
1330 status = avrcp_controller_disable_notification(avrcp_connection->avrcp_cid, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED);
1331 break;
1332 case 'R':
1333 printf("AVRCP: enable notification PLAYBACK_POS_CHANGED\n");
1334 status = avrcp_controller_enable_notification(avrcp_connection->avrcp_cid, AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED);
1335 break;
1336 case 'P':
1337 printf("AVRCP: disable notification PLAYBACK_POS_CHANGED\n");
1338 status = avrcp_controller_disable_notification(avrcp_connection->avrcp_cid, AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED);
1339 break;
1340 case 's':
1341 printf("AVRCP: send long button press REWIND\n");
1342 status = avrcp_controller_start_press_and_hold_cmd(avrcp_connection->avrcp_cid, AVRCP_OPERATION_ID_REWIND);
1343 break;
1344 case 'S':
1345 printf("AVRCP: release long button press REWIND\n");
1346 status = avrcp_controller_release_press_and_hold_cmd(avrcp_connection->avrcp_cid);
1347 break;
1348 #ifdef ENABLE_AVRCP_COVER_ART
1349 case 'd':
1350 printf(" - Create AVRCP Cover Art connection to addr %s.\n", bd_addr_to_str(device_addr));
1351 status = a2dp_sink_demo_cover_art_connect();
1352 break;
1353 case 'D':
1354 printf(" - AVRCP Cover Art disconnect from addr %s.\n", bd_addr_to_str(device_addr));
1355 status = avrcp_cover_art_client_disconnect(a2dp_sink_demo_cover_art_cid);
1356 break;
1357 case '@':
1358 printf("Get linked thumbnail for '%s'\n", a2dp_sink_demo_image_handle);
1359 #ifdef HAVE_POSIX_FILE_IO
1360 a2dp_sink_cover_art_file = fopen(a2dp_sink_demo_thumbnail_path, "w");
1361 #endif
1362 a2dp_sink_cover_art_download_active = true;
1363 a2dp_sink_cover_art_file_size = 0;
1364 status = avrcp_cover_art_client_get_linked_thumbnail(a2dp_sink_demo_cover_art_cid, a2dp_sink_demo_image_handle);
1365 break;
1366 #endif
1367 default:
1368 show_usage();
1369 return;
1370 }
1371 if (status != ERROR_CODE_SUCCESS){
1372 printf("Could not perform command, status 0x%02x\n", status);
1373 }
1374 }
1375 #endif
1376
1377 int btstack_main(int argc, const char * argv[]);
btstack_main(int argc,const char * argv[])1378 int btstack_main(int argc, const char * argv[]){
1379 UNUSED(argc);
1380 (void)argv;
1381
1382 setup_demo();
1383
1384 #ifdef HAVE_BTSTACK_STDIN
1385 // parse human-readable Bluetooth address
1386 sscanf_bd_addr(device_addr_string, device_addr);
1387 btstack_stdin_setup(stdin_process);
1388 #endif
1389
1390 // turn on!
1391 printf("Starting BTstack ...\n");
1392 hci_power_control(HCI_POWER_ON);
1393 return 0;
1394 }
1395 /* EXAMPLE_END */
1396