1 /* 2 * Copyright (C) 2016 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 MATTHIAS 24 * RINGWALD 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_source_demo.c" 39 40 /* 41 * a2dp_source_demo.c 42 */ 43 44 // ***************************************************************************** 45 /* EXAMPLE_START(a2dp_source_demo): Serve audio stream and handle remote playback control and queries. 46 * 47 * @text This A2DP Source example demonstrates how to send an audio data stream 48 * to a remote A2DP Sink device and how to switch between two audio data sources. 49 * In addition, the AVRCP Target is used to answer queries on currently played media, 50 * as well as to handle remote playback control, i.e. play, stop, repeat, etc. 51 * 52 * @test To test with a remote device, e.g. a Bluetooth speaker, 53 * set the device_addr_string to the Bluetooth address of your 54 * remote device in the code, and use the UI to connect and start playback. 55 * Tap SPACE on the console to show the available commands. 56 */ 57 // ***************************************************************************** 58 59 60 #include <stdint.h> 61 #include <stdio.h> 62 #include <stdlib.h> 63 #include <string.h> 64 65 #include "btstack.h" 66 #include "hxcmod.h" 67 #include "mods/mod.h" 68 69 // logarithmic volume reduction, samples are divided by 2^x 70 // #define VOLUME_REDUCTION 3 71 // #undef HAVE_BTSTACK_STDIN 72 73 //#define AVRCP_BROWSING_ENABLED 74 75 #define NUM_CHANNELS 2 76 #define A2DP_SAMPLE_RATE 44100 77 #define BYTES_PER_AUDIO_SAMPLE (2*NUM_CHANNELS) 78 #define AUDIO_TIMEOUT_MS 10 79 #define TABLE_SIZE_441HZ 100 80 81 #define SBC_STORAGE_SIZE 1030 82 83 typedef enum { 84 STREAM_SINE = 0, 85 STREAM_MOD, 86 STREAM_PTS_TEST 87 } stream_data_source_t; 88 89 typedef struct { 90 uint16_t a2dp_cid; 91 uint8_t local_seid; 92 uint8_t stream_opened; 93 uint16_t avrcp_cid; 94 95 uint32_t time_audio_data_sent; // ms 96 uint32_t acc_num_missed_samples; 97 uint32_t samples_ready; 98 btstack_timer_source_t audio_timer; 99 uint8_t streaming; 100 int max_media_payload_size; 101 102 uint8_t sbc_storage[SBC_STORAGE_SIZE]; 103 uint16_t sbc_storage_count; 104 uint8_t sbc_ready_to_send; 105 } a2dp_media_sending_context_t; 106 107 static uint8_t media_sbc_codec_capabilities[] = { 108 (AVDTP_SBC_44100 << 4) | AVDTP_SBC_STEREO, 109 0xFF,//(AVDTP_SBC_BLOCK_LENGTH_16 << 4) | (AVDTP_SBC_SUBBANDS_8 << 2) | AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS, 110 2, 53 111 }; 112 113 static const int16_t sine_int16[] = { 114 0, 2057, 4107, 6140, 8149, 10126, 12062, 13952, 15786, 17557, 115 19260, 20886, 22431, 23886, 25247, 26509, 27666, 28714, 29648, 30466, 116 31163, 31738, 32187, 32509, 32702, 32767, 32702, 32509, 32187, 31738, 117 31163, 30466, 29648, 28714, 27666, 26509, 25247, 23886, 22431, 20886, 118 19260, 17557, 15786, 13952, 12062, 10126, 8149, 6140, 4107, 2057, 119 0, -2057, -4107, -6140, -8149, -10126, -12062, -13952, -15786, -17557, 120 -19260, -20886, -22431, -23886, -25247, -26509, -27666, -28714, -29648, -30466, 121 -31163, -31738, -32187, -32509, -32702, -32767, -32702, -32509, -32187, -31738, 122 -31163, -30466, -29648, -28714, -27666, -26509, -25247, -23886, -22431, -20886, 123 -19260, -17557, -15786, -13952, -12062, -10126, -8149, -6140, -4107, -2057, 124 }; 125 126 typedef struct { 127 int reconfigure; 128 int num_channels; 129 int sampling_frequency; 130 int channel_mode; 131 int block_length; 132 int subbands; 133 int allocation_method; 134 int min_bitpool_value; 135 int max_bitpool_value; 136 int frames_per_buffer; 137 } avdtp_media_codec_configuration_sbc_t; 138 139 static btstack_packet_callback_registration_t hci_event_callback_registration; 140 141 // pts: static const char * device_addr_string = "00:1B:DC:08:0A:A5"; 142 // pts: static const char * device_addr_string = "00:1B:DC:08:E2:72"; 143 // mac 2013: static const char * device_addr_string = "84:38:35:65:d1:15"; 144 // phone 2013: static const char * device_addr_string = "D8:BB:2C:DF:F0:F2"; 145 // Minijambox: static const char * device_addr_string = "00:21:3C:AC:F7:38"; 146 // Philips SHB9100: static const char * device_addr_string = "00:22:37:05:FD:E8"; 147 // RT-B6: static const char * device_addr_string = "00:75:58:FF:C9:7D"; 148 // BT dongle: static const char * device_addr_string = "00:1A:7D:DA:71:0A"; 149 // Sony MDR-ZX330BT 150 static const char * device_addr_string = "00:18:09:28:50:18"; 151 // Panda (BM6) static const char * device_addr_string = "4F:3F:66:52:8B:E0"; 152 153 static bd_addr_t device_addr; 154 static uint8_t sdp_a2dp_source_service_buffer[150]; 155 static uint8_t sdp_avrcp_target_service_buffer[200]; 156 static uint8_t sdp_avrcp_controller_service_buffer[200]; 157 158 static avdtp_media_codec_configuration_sbc_t sbc_configuration; 159 static btstack_sbc_encoder_state_t sbc_encoder_state; 160 161 static uint8_t media_sbc_codec_configuration[4]; 162 static a2dp_media_sending_context_t media_tracker; 163 164 static stream_data_source_t data_source; 165 166 static int sine_phase; 167 168 static int hxcmod_initialized; 169 static modcontext mod_context; 170 static tracker_buffer_state trkbuf; 171 172 static uint16_t avrcp_controller_cid = 0; 173 174 /* AVRCP Target context START */ 175 static const uint8_t subunit_info[] = { 176 0,0,0,0, 177 1,1,1,1, 178 2,2,2,2, 179 3,3,3,3, 180 4,4,4,4, 181 5,5,5,5, 182 6,6,6,6, 183 7,7,7,7 184 }; 185 186 static uint32_t company_id = 0x112233; 187 static uint8_t companies_num = 1; 188 static uint8_t companies[] = { 189 0x00, 0x19, 0x58 //BT SIG registered CompanyID 190 }; 191 192 static uint8_t events_num = 13; 193 static uint8_t events[] = { 194 AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED, 195 AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED, 196 AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_END, 197 AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_START, 198 AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED, 199 AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED, 200 AVRCP_NOTIFICATION_EVENT_SYSTEM_STATUS_CHANGED, 201 AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED, 202 AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED, 203 AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED, 204 AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED, 205 AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED, 206 AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED 207 }; 208 209 typedef struct { 210 uint8_t track_id[8]; 211 uint32_t song_length_ms; 212 avrcp_playback_status_t status; 213 uint32_t song_position_ms; // 0xFFFFFFFF if not supported 214 } avrcp_play_status_info_t; 215 216 // python -c "print('a'*512)" 217 static const char title[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 218 219 avrcp_track_t tracks[] = { 220 {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 1, "Sine", "Generated", "A2DP Source Demo", "monotone", 12345}, 221 {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, 2, "Nao-deceased", "Decease", "A2DP Source Demo", "vivid", 12345}, 222 {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}, 3, (char *)title, "Decease", "A2DP Source Demo", "vivid", 12345}, 223 }; 224 int current_track_index; 225 avrcp_play_status_info_t play_info; 226 227 /* AVRCP Target context END */ 228 229 /* @section Main Application Setup 230 * 231 * @text The Listing MainConfiguration shows how to setup AD2P Source and AVRCP Target services. 232 */ 233 234 /* LISTING_START(MainConfiguration): Setup Audio Source and AVRCP Target services */ 235 static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size); 236 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 237 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 238 #ifdef HAVE_BTSTACK_STDIN 239 static void stdin_process(char cmd); 240 #endif 241 242 static int a2dp_source_and_avrcp_services_init(void){ 243 244 l2cap_init(); 245 // Initialize A2DP Source. 246 a2dp_source_init(); 247 a2dp_source_register_packet_handler(&a2dp_source_packet_handler); 248 249 // Create stream endpoint. 250 avdtp_stream_endpoint_t * local_stream_endpoint = a2dp_source_create_stream_endpoint(AVDTP_AUDIO, AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities), media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration)); 251 if (!local_stream_endpoint){ 252 printf("A2DP Source: not enough memory to create local stream endpoint\n"); 253 return 1; 254 } 255 media_tracker.local_seid = avdtp_local_seid(local_stream_endpoint); 256 avdtp_source_register_delay_reporting_category(media_tracker.local_seid); 257 258 // Initialize AVRCP Target. 259 avrcp_target_init(); 260 avrcp_target_register_packet_handler(&avrcp_target_packet_handler); 261 // Initialize AVRCP Controller 262 avrcp_controller_init(); 263 avrcp_controller_register_packet_handler(&avrcp_controller_packet_handler); 264 265 // Initialize SDP, 266 sdp_init(); 267 268 // Create A2DP Source service record and register it with SDP. 269 memset(sdp_a2dp_source_service_buffer, 0, sizeof(sdp_a2dp_source_service_buffer)); 270 a2dp_source_create_sdp_record(sdp_a2dp_source_service_buffer, 0x10002, 1, NULL, NULL); 271 sdp_register_service(sdp_a2dp_source_service_buffer); 272 273 // Create AVRCP target service record and register it with SDP. 274 memset(sdp_avrcp_target_service_buffer, 0, sizeof(sdp_avrcp_target_service_buffer)); 275 uint16_t supported_features = (1 << AVRCP_TARGET_SUPPORTED_FEATURE_CATEGORY_PLAYER_OR_RECORDER); 276 #ifdef AVRCP_BROWSING_ENABLED 277 supported_features |= (1 << AVRCP_TARGET_SUPPORTED_FEATURE_BROWSING); 278 #endif 279 avrcp_target_create_sdp_record(sdp_avrcp_target_service_buffer, 0x10001, supported_features, NULL, NULL); 280 sdp_register_service(sdp_avrcp_target_service_buffer); 281 282 // setup AVRCP Controller 283 memset(sdp_avrcp_controller_service_buffer, 0, sizeof(sdp_avrcp_controller_service_buffer)); 284 uint16_t controller_supported_features = (1 << AVRCP_CONTROLLER_SUPPORTED_FEATURE_CATEGORY_MONITOR_OR_AMPLIFIER); 285 avrcp_controller_create_sdp_record(sdp_avrcp_controller_service_buffer, 0x10002, controller_supported_features, NULL, NULL); 286 sdp_register_service(sdp_avrcp_controller_service_buffer); 287 288 // Set local name with a template Bluetooth address, that will be automatically 289 // replaced with a actual address once it is available, i.e. when BTstack boots 290 // up and starts talking to a Bluetooth module. 291 gap_set_local_name("A2DP Source 00:00:00:00:00:00"); 292 gap_discoverable_control(1); 293 gap_set_class_of_device(0x200408); 294 295 // Register for HCI events. 296 hci_event_callback_registration.callback = &a2dp_source_packet_handler; 297 hci_add_event_handler(&hci_event_callback_registration); 298 299 hxcmod_initialized = hxcmod_init(&mod_context); 300 if (hxcmod_initialized){ 301 hxcmod_setcfg(&mod_context, A2DP_SAMPLE_RATE, 16, 1, 1, 1); 302 hxcmod_load(&mod_context, (void *) &mod_data, mod_len); 303 printf("loaded mod '%s', size %u\n", mod_name, mod_len); 304 } 305 306 // Parse human readable Bluetooth address. 307 sscanf_bd_addr(device_addr_string, device_addr); 308 309 #ifdef HAVE_BTSTACK_STDIN 310 btstack_stdin_setup(stdin_process); 311 #endif 312 return 0; 313 } 314 /* LISTING_END */ 315 316 static void a2dp_demo_send_media_packet(void){ 317 int num_bytes_in_frame = btstack_sbc_encoder_sbc_buffer_length(); 318 int bytes_in_storage = media_tracker.sbc_storage_count; 319 uint8_t num_frames = bytes_in_storage / num_bytes_in_frame; 320 a2dp_source_stream_send_media_payload(media_tracker.a2dp_cid, media_tracker.local_seid, media_tracker.sbc_storage, bytes_in_storage, num_frames, 0); 321 media_tracker.sbc_storage_count = 0; 322 media_tracker.sbc_ready_to_send = 0; 323 } 324 325 static void produce_sine_audio(int16_t * pcm_buffer, int num_samples_to_write){ 326 int count; 327 for (count = 0; count < num_samples_to_write ; count++){ 328 pcm_buffer[count * 2] = sine_int16[sine_phase]; 329 pcm_buffer[count * 2 + 1] = sine_int16[sine_phase]; 330 sine_phase++; 331 if (sine_phase >= TABLE_SIZE_441HZ){ 332 sine_phase -= TABLE_SIZE_441HZ; 333 } 334 } 335 } 336 337 static void produce_mod_audio(int16_t * pcm_buffer, int num_samples_to_write){ 338 hxcmod_fillbuffer(&mod_context, (unsigned short *) &pcm_buffer[0], num_samples_to_write, &trkbuf); 339 } 340 341 static void produce_audio(int16_t * pcm_buffer, int num_samples){ 342 switch (data_source){ 343 case STREAM_SINE: 344 produce_sine_audio(pcm_buffer, num_samples); 345 break; 346 case STREAM_MOD: 347 produce_mod_audio(pcm_buffer, num_samples); 348 break; 349 default: 350 break; 351 } 352 #ifdef VOLUME_REDUCTION 353 int i; 354 for (i=0;i<num_samples*2;i++){ 355 if (pcm_buffer[i] > 0){ 356 pcm_buffer[i] = pcm_buffer[i] >> VOLUME_REDUCTION; 357 } else { 358 pcm_buffer[i] = -((-pcm_buffer[i]) >> VOLUME_REDUCTION); 359 } 360 } 361 #endif 362 } 363 364 static int a2dp_demo_fill_sbc_audio_buffer(a2dp_media_sending_context_t * context){ 365 // perform sbc encodin 366 int total_num_bytes_read = 0; 367 unsigned int num_audio_samples_per_sbc_buffer = btstack_sbc_encoder_num_audio_frames(); 368 while (context->samples_ready >= num_audio_samples_per_sbc_buffer 369 && (context->max_media_payload_size - context->sbc_storage_count) >= btstack_sbc_encoder_sbc_buffer_length()){ 370 371 int16_t pcm_frame[256*NUM_CHANNELS]; 372 373 produce_audio(pcm_frame, num_audio_samples_per_sbc_buffer); 374 btstack_sbc_encoder_process_data(pcm_frame); 375 376 uint16_t sbc_frame_size = btstack_sbc_encoder_sbc_buffer_length(); 377 uint8_t * sbc_frame = btstack_sbc_encoder_sbc_buffer(); 378 379 total_num_bytes_read += num_audio_samples_per_sbc_buffer; 380 memcpy(&context->sbc_storage[context->sbc_storage_count], sbc_frame, sbc_frame_size); 381 context->sbc_storage_count += sbc_frame_size; 382 context->samples_ready -= num_audio_samples_per_sbc_buffer; 383 } 384 return total_num_bytes_read; 385 } 386 387 static void a2dp_demo_audio_timeout_handler(btstack_timer_source_t * timer){ 388 a2dp_media_sending_context_t * context = (a2dp_media_sending_context_t *) btstack_run_loop_get_timer_context(timer); 389 btstack_run_loop_set_timer(&context->audio_timer, AUDIO_TIMEOUT_MS); 390 btstack_run_loop_add_timer(&context->audio_timer); 391 uint32_t now = btstack_run_loop_get_time_ms(); 392 393 uint32_t update_period_ms = AUDIO_TIMEOUT_MS; 394 if (context->time_audio_data_sent > 0){ 395 update_period_ms = now - context->time_audio_data_sent; 396 } 397 398 uint32_t num_samples = (update_period_ms * A2DP_SAMPLE_RATE) / 1000; 399 context->acc_num_missed_samples += (update_period_ms * A2DP_SAMPLE_RATE) % 1000; 400 401 while (context->acc_num_missed_samples >= 1000){ 402 num_samples++; 403 context->acc_num_missed_samples -= 1000; 404 } 405 context->time_audio_data_sent = now; 406 context->samples_ready += num_samples; 407 408 if (context->sbc_ready_to_send) return; 409 410 a2dp_demo_fill_sbc_audio_buffer(context); 411 412 if ((context->sbc_storage_count + btstack_sbc_encoder_sbc_buffer_length()) > context->max_media_payload_size){ 413 // schedule sending 414 context->sbc_ready_to_send = 1; 415 a2dp_source_stream_endpoint_request_can_send_now(context->a2dp_cid, context->local_seid); 416 } 417 } 418 419 static void a2dp_demo_timer_start(a2dp_media_sending_context_t * context){ 420 context->max_media_payload_size = btstack_min(a2dp_max_media_payload_size(context->a2dp_cid, context->local_seid), SBC_STORAGE_SIZE); 421 context->sbc_storage_count = 0; 422 context->sbc_ready_to_send = 0; 423 context->streaming = 1; 424 btstack_run_loop_remove_timer(&context->audio_timer); 425 btstack_run_loop_set_timer_handler(&context->audio_timer, a2dp_demo_audio_timeout_handler); 426 btstack_run_loop_set_timer_context(&context->audio_timer, context); 427 btstack_run_loop_set_timer(&context->audio_timer, AUDIO_TIMEOUT_MS); 428 btstack_run_loop_add_timer(&context->audio_timer); 429 } 430 431 static void a2dp_demo_timer_stop(a2dp_media_sending_context_t * context){ 432 context->time_audio_data_sent = 0; 433 context->acc_num_missed_samples = 0; 434 context->samples_ready = 0; 435 context->streaming = 1; 436 context->sbc_storage_count = 0; 437 context->sbc_ready_to_send = 0; 438 btstack_run_loop_remove_timer(&context->audio_timer); 439 } 440 441 static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t * configuration){ 442 printf("Received media codec configuration:\n"); 443 printf(" - num_channels: %d\n", configuration->num_channels); 444 printf(" - sampling_frequency: %d\n", configuration->sampling_frequency); 445 printf(" - channel_mode: %d\n", configuration->channel_mode); 446 printf(" - block_length: %d\n", configuration->block_length); 447 printf(" - subbands: %d\n", configuration->subbands); 448 printf(" - allocation_method: %d\n", configuration->allocation_method); 449 printf(" - bitpool_value [%d, %d] \n", configuration->min_bitpool_value, configuration->max_bitpool_value); 450 } 451 452 static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 453 UNUSED(channel); 454 UNUSED(size); 455 uint8_t status; 456 uint8_t local_seid; 457 bd_addr_t address; 458 uint16_t cid; 459 460 if (packet_type != HCI_EVENT_PACKET) return; 461 462 #ifndef HAVE_BTSTACK_STDIN 463 if (hci_event_packet_get_type(packet) == BTSTACK_EVENT_STATE){ 464 if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; 465 printf("Create A2DP Source connection to addr %s.\n", bd_addr_to_str(device_addr)); 466 status = a2dp_source_establish_stream(device_addr, media_tracker.local_seid, &media_tracker.a2dp_cid); 467 if (status != ERROR_CODE_SUCCESS){ 468 printf("Could not perform command, status 0x%2x\n", status); 469 } 470 return; 471 } 472 #endif 473 if (hci_event_packet_get_type(packet) == HCI_EVENT_PIN_CODE_REQUEST) { 474 printf("Pin code request - using '0000'\n"); 475 hci_event_pin_code_request_get_bd_addr(packet, address); 476 gap_pin_code_response(address, "0000"); 477 return; 478 } 479 480 if (hci_event_packet_get_type(packet) != HCI_EVENT_A2DP_META) return; 481 482 switch (hci_event_a2dp_meta_get_subevent_code(packet)){ 483 case A2DP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED: 484 a2dp_subevent_signaling_connection_established_get_bd_addr(packet, address); 485 cid = a2dp_subevent_signaling_connection_established_get_a2dp_cid(packet); 486 status = a2dp_subevent_signaling_connection_established_get_status(packet); 487 488 if (status != ERROR_CODE_SUCCESS){ 489 printf("A2DP Source: Connection failed, status 0x%02x, cid 0x%02x, a2dp_cid 0x%02x \n", status, cid, media_tracker.a2dp_cid); 490 media_tracker.a2dp_cid = 0; 491 break; 492 } 493 media_tracker.a2dp_cid = cid; 494 printf("A2DP Source: Connected to address %s, a2dp cid 0x%02x.\n", bd_addr_to_str(address), media_tracker.a2dp_cid); 495 break; 496 497 case A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{ 498 cid = avdtp_subevent_signaling_media_codec_sbc_configuration_get_avdtp_cid(packet); 499 if (cid != media_tracker.a2dp_cid) return; 500 501 sbc_configuration.reconfigure = a2dp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet); 502 sbc_configuration.num_channels = a2dp_subevent_signaling_media_codec_sbc_configuration_get_num_channels(packet); 503 sbc_configuration.sampling_frequency = a2dp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet); 504 sbc_configuration.channel_mode = a2dp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet); 505 sbc_configuration.block_length = a2dp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet); 506 sbc_configuration.subbands = a2dp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet); 507 sbc_configuration.allocation_method = a2dp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet); 508 sbc_configuration.min_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_min_bitpool_value(packet); 509 sbc_configuration.max_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet); 510 sbc_configuration.frames_per_buffer = sbc_configuration.subbands * sbc_configuration.block_length; 511 printf("A2DP Source: Received SBC codec configuration, sampling frequency %u.\n", sbc_configuration.sampling_frequency); 512 513 // Adapt Bluetooth spec definition to SBC Encoder expected input 514 sbc_configuration.allocation_method -= 1; 515 sbc_configuration.num_channels = 2; 516 switch (sbc_configuration.channel_mode){ 517 case AVDTP_SBC_JOINT_STEREO: 518 sbc_configuration.channel_mode = 3; 519 break; 520 case AVDTP_SBC_STEREO: 521 sbc_configuration.channel_mode = 2; 522 break; 523 case AVDTP_SBC_DUAL_CHANNEL: 524 sbc_configuration.channel_mode = 1; 525 break; 526 case AVDTP_SBC_MONO: 527 sbc_configuration.channel_mode = 0; 528 sbc_configuration.num_channels = 1; 529 break; 530 } 531 dump_sbc_configuration(&sbc_configuration); 532 533 btstack_sbc_encoder_init(&sbc_encoder_state, SBC_MODE_STANDARD, 534 sbc_configuration.block_length, sbc_configuration.subbands, 535 sbc_configuration.allocation_method, sbc_configuration.sampling_frequency, 536 sbc_configuration.max_bitpool_value, 537 sbc_configuration.channel_mode); 538 break; 539 } 540 541 case A2DP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY: 542 printf("A2DP Source: remote supports delay report\n"); 543 break; 544 case A2DP_SUBEVENT_SIGNALING_CAPABILITIES_DONE: 545 printf("A2DP Source: All capabilities reported\n"); 546 break; 547 548 case A2DP_SUBEVENT_SIGNALING_DELAY_REPORT: 549 printf("A2DP Source: Received delay report of %d.%0d ms, local seid %d\n", 550 avdtp_subevent_signaling_delay_report_get_delay_100us(packet)/10, avdtp_subevent_signaling_delay_report_get_delay_100us(packet)%10, 551 avdtp_subevent_signaling_delay_report_get_local_seid(packet)); 552 break; 553 554 case A2DP_SUBEVENT_STREAM_ESTABLISHED: 555 a2dp_subevent_stream_established_get_bd_addr(packet, address); 556 status = a2dp_subevent_stream_established_get_status(packet); 557 if (status){ 558 printf("A2DP Source: Stream failed, status 0x%02x.\n", status); 559 break; 560 } 561 local_seid = a2dp_subevent_stream_established_get_local_seid(packet); 562 if (local_seid != media_tracker.local_seid){ 563 printf("A2DP Source: Stream failed, wrong local seid %d, expected %d.\n", local_seid, media_tracker.local_seid); 564 break; 565 } 566 printf("A2DP Source: Stream established, address %s, a2dp cid 0x%02x, local seid %d, remote seid %d.\n", bd_addr_to_str(address), 567 media_tracker.a2dp_cid, media_tracker.local_seid, a2dp_subevent_stream_established_get_remote_seid(packet)); 568 media_tracker.stream_opened = 1; 569 data_source = STREAM_MOD; 570 status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid); 571 break; 572 573 case A2DP_SUBEVENT_STREAM_RECONFIGURED: 574 status = a2dp_subevent_stream_reconfigured_get_status(packet); 575 printf("A2DP Source: Reconfigured, status 0x%02x\n", status); 576 break; 577 578 case A2DP_SUBEVENT_STREAM_STARTED: 579 play_info.status = AVRCP_PLAYBACK_STATUS_PLAYING; 580 if (media_tracker.avrcp_cid){ 581 avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t)); 582 avrcp_target_set_playback_status(media_tracker.avrcp_cid, AVRCP_PLAYBACK_STATUS_PLAYING); 583 } 584 a2dp_demo_timer_start(&media_tracker); 585 printf("A2DP Source: Stream started.\n"); 586 break; 587 588 case A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW: 589 a2dp_demo_send_media_packet(); 590 break; 591 592 case A2DP_SUBEVENT_STREAM_SUSPENDED: 593 play_info.status = AVRCP_PLAYBACK_STATUS_PAUSED; 594 if (media_tracker.avrcp_cid){ 595 avrcp_target_set_playback_status(media_tracker.avrcp_cid, AVRCP_PLAYBACK_STATUS_PAUSED); 596 } 597 printf("A2DP Source: Stream paused.\n"); 598 a2dp_demo_timer_stop(&media_tracker); 599 break; 600 601 case A2DP_SUBEVENT_STREAM_RELEASED: 602 play_info.status = AVRCP_PLAYBACK_STATUS_STOPPED; 603 cid = a2dp_subevent_stream_released_get_a2dp_cid(packet); 604 if (cid == media_tracker.a2dp_cid) { 605 media_tracker.stream_opened = 0; 606 printf("A2DP Source: Stream released.\n"); 607 } 608 if (media_tracker.avrcp_cid){ 609 avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, NULL, sizeof(tracks)/sizeof(avrcp_track_t)); 610 avrcp_target_set_playback_status(media_tracker.avrcp_cid, AVRCP_PLAYBACK_STATUS_STOPPED); 611 } 612 a2dp_demo_timer_stop(&media_tracker); 613 break; 614 case A2DP_SUBEVENT_SIGNALING_CONNECTION_RELEASED: 615 cid = a2dp_subevent_signaling_connection_released_get_a2dp_cid(packet); 616 if (cid == media_tracker.a2dp_cid) { 617 media_tracker.avrcp_cid = 0; 618 media_tracker.a2dp_cid = 0; 619 printf("A2DP Source: Signaling released.\n\n"); 620 } 621 break; 622 default: 623 break; 624 } 625 } 626 627 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 628 UNUSED(channel); 629 UNUSED(size); 630 bd_addr_t event_addr; 631 uint16_t local_cid; 632 uint8_t status = ERROR_CODE_SUCCESS; 633 634 if (packet_type != HCI_EVENT_PACKET) return; 635 if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return; 636 637 switch (packet[2]){ 638 case AVRCP_SUBEVENT_CONNECTION_ESTABLISHED: { 639 local_cid = avrcp_subevent_connection_established_get_avrcp_cid(packet); 640 // if (avrcp_cid != 0 && avrcp_cid != local_cid) { 641 // printf("AVRCP Target: Connection failed, expected 0x%02X l2cap cid, received 0x%02X\n", avrcp_cid, local_cid); 642 // return; 643 // } 644 // if (avrcp_cid != local_cid) break; 645 646 status = avrcp_subevent_connection_established_get_status(packet); 647 if (status != ERROR_CODE_SUCCESS){ 648 printf("AVRCP Target: Connection failed, status 0x%02x\n", status); 649 return; 650 } 651 media_tracker.avrcp_cid = local_cid; 652 avrcp_subevent_connection_established_get_bd_addr(packet, event_addr); 653 printf("AVRCP Target: Connected to %s, avrcp_cid 0x%02x\n", bd_addr_to_str(event_addr), local_cid); 654 655 avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, NULL, sizeof(tracks)/sizeof(avrcp_track_t)); 656 avrcp_target_set_unit_info(media_tracker.avrcp_cid, AVRCP_SUBUNIT_TYPE_AUDIO, company_id); 657 avrcp_target_set_subunit_info(media_tracker.avrcp_cid, AVRCP_SUBUNIT_TYPE_AUDIO, (uint8_t *)subunit_info, sizeof(subunit_info)); 658 return; 659 } 660 case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED: 661 printf("AVRCP Target: new volume %d\n", avrcp_subevent_notification_volume_changed_get_absolute_volume(packet)); 662 break; 663 case AVRCP_SUBEVENT_EVENT_IDS_QUERY: 664 status = avrcp_target_supported_events(media_tracker.avrcp_cid, events_num, events, sizeof(events)); 665 break; 666 case AVRCP_SUBEVENT_COMPANY_IDS_QUERY: 667 status = avrcp_target_supported_companies(media_tracker.avrcp_cid, companies_num, companies, sizeof(companies)); 668 break; 669 case AVRCP_SUBEVENT_PLAY_STATUS_QUERY: 670 status = avrcp_target_play_status(media_tracker.avrcp_cid, play_info.song_length_ms, play_info.song_position_ms, play_info.status); 671 break; 672 // case AVRCP_SUBEVENT_NOW_PLAYING_INFO_QUERY: 673 // status = avrcp_target_now_playing_info(avrcp_cid); 674 // break; 675 case AVRCP_SUBEVENT_OPERATION:{ 676 avrcp_operation_id_t operation_id = avrcp_subevent_operation_get_operation_id(packet); 677 switch (operation_id){ 678 case AVRCP_OPERATION_ID_PLAY: 679 printf("AVRCP Target: PLAY\n"); 680 status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid); 681 break; 682 case AVRCP_OPERATION_ID_PAUSE: 683 printf("AVRCP Target: PAUSE\n"); 684 status = a2dp_source_pause_stream(media_tracker.a2dp_cid, media_tracker.local_seid); 685 break; 686 case AVRCP_OPERATION_ID_STOP: 687 printf("AVRCP Target: STOP\n"); 688 status = a2dp_source_disconnect(media_tracker.a2dp_cid); 689 break; 690 default: 691 printf("AVRCP Target: operation 0x%2x is not handled\n", operation_id); 692 return; 693 } 694 break; 695 } 696 case AVRCP_SUBEVENT_CONNECTION_RELEASED: 697 printf("AVRCP Target: Disconnected, avrcp_cid 0x%02x\n", avrcp_subevent_connection_released_get_avrcp_cid(packet)); 698 media_tracker.avrcp_cid = 0; 699 return; 700 default: 701 break; 702 } 703 704 if (status != ERROR_CODE_SUCCESS){ 705 printf("Responding to event 0x%02x failed with status 0x%02x\n", packet[2], status); 706 } 707 } 708 709 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 710 UNUSED(channel); 711 UNUSED(size); 712 uint16_t local_cid; 713 uint8_t status = 0xFF; 714 bd_addr_t adress; 715 716 if (packet_type != HCI_EVENT_PACKET) return; 717 if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return; 718 switch (packet[2]){ 719 case AVRCP_SUBEVENT_CONNECTION_ESTABLISHED: { 720 local_cid = avrcp_subevent_connection_established_get_avrcp_cid(packet); 721 if (avrcp_controller_cid != 0 && avrcp_controller_cid != local_cid) { 722 printf("AVRCP Controller: Connection failed, expected 0x%02X l2cap cid, received 0x%02X\n", avrcp_controller_cid, local_cid); 723 return; 724 } 725 726 status = avrcp_subevent_connection_established_get_status(packet); 727 if (status != ERROR_CODE_SUCCESS){ 728 printf("AVRCP Controller: Connection failed: status 0x%02x\n", status); 729 avrcp_controller_cid = 0; 730 return; 731 } 732 733 avrcp_controller_cid = local_cid; 734 avrcp_subevent_connection_established_get_bd_addr(packet, adress); 735 printf("AVRCP Controller: Channel successfully opened: %s, avrcp_controller_cid 0x%02x\n", bd_addr_to_str(adress), avrcp_controller_cid); 736 737 // automatically enable notifications 738 avrcp_controller_enable_notification(avrcp_controller_cid, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED); 739 return; 740 } 741 case AVRCP_SUBEVENT_CONNECTION_RELEASED: 742 printf("AVRCP Controller: Channel released: avrcp_controller_cid 0x%02x\n", avrcp_subevent_connection_released_get_avrcp_cid(packet)); 743 avrcp_controller_cid = 0; 744 return; 745 default: 746 break; 747 } 748 749 status = packet[5]; 750 if (!avrcp_controller_cid) return; 751 752 // ignore INTERIM status 753 if (status == AVRCP_CTYPE_RESPONSE_INTERIM) return; 754 755 switch (packet[2]){ 756 case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:{ 757 int volume_percentage = avrcp_subevent_notification_volume_changed_get_absolute_volume(packet) * 100 / 127; 758 printf("AVRCP Controller: notification absolute volume changed %d %%\n", volume_percentage); 759 return; 760 } 761 default: 762 break; 763 } 764 } 765 766 #ifdef HAVE_BTSTACK_STDIN 767 static void show_usage(void){ 768 bd_addr_t iut_address; 769 gap_local_bd_addr(iut_address); 770 printf("\n--- Bluetooth A2DP Source/AVRCP Target Demo %s ---\n", bd_addr_to_str(iut_address)); 771 printf("b - A2DP Source create connection to addr %s\n", device_addr_string); 772 printf("B - A2DP Source disconnect\n"); 773 printf("c - AVRCP Target create connection to addr %s\n", device_addr_string); 774 printf("C - AVRCP Target disconnect\n"); 775 776 printf("x - start streaming sine\n"); 777 if (hxcmod_initialized){ 778 printf("z - start streaming '%s'\n", mod_name); 779 } 780 printf("p - pause streaming\n"); 781 printf("w - reconfigure stream for 44100 Hz\n"); 782 printf("e - reconfigure stream for 48000 Hz\n"); 783 printf("t - volume up\n"); 784 printf("T - volume down\n"); 785 printf("v - absolute volume of 50 percent\n"); 786 787 printf("\n--- Bluetooth AVRCP Target Commands %s ---\n", bd_addr_to_str(iut_address)); 788 printf("---\n"); 789 } 790 791 static void stdin_process(char cmd){ 792 uint8_t status = ERROR_CODE_SUCCESS; 793 switch (cmd){ 794 case 'b': 795 status = a2dp_source_establish_stream(device_addr, media_tracker.local_seid, &media_tracker.a2dp_cid); 796 printf("%c - Create A2DP Source connection to addr %s, cid 0x%02x.\n", cmd, bd_addr_to_str(device_addr), media_tracker.a2dp_cid); 797 break; 798 case 'B': 799 printf("%c - A2DP Source Disconnect from cid 0x%2x\n", cmd, media_tracker.a2dp_cid); 800 status = a2dp_source_disconnect(media_tracker.a2dp_cid); 801 break; 802 case 'c': 803 printf("%c - Create AVRCP Target connection to addr %s.\n", cmd, bd_addr_to_str(device_addr)); 804 status = avrcp_target_connect(device_addr, &media_tracker.avrcp_cid); 805 break; 806 case 'C': 807 printf("%c - AVRCP Target disconnect\n", cmd); 808 status = avrcp_target_disconnect(media_tracker.avrcp_cid); 809 break; 810 811 case '\n': 812 case '\r': 813 break; 814 815 case 't': 816 printf(" - volume up\n"); 817 status = avrcp_controller_volume_up(avrcp_controller_cid); 818 break; 819 case 'T': 820 printf(" - volume down\n"); 821 status = avrcp_controller_volume_down(avrcp_controller_cid); 822 break; 823 case 'v': 824 printf(" - absolute volume of 50%% (64)\n"); 825 status = avrcp_controller_set_absolute_volume(avrcp_controller_cid, 64); 826 break; 827 828 case 'x': 829 if (media_tracker.avrcp_cid){ 830 avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t)); 831 } 832 printf("%c - Play sine.\n", cmd); 833 data_source = STREAM_SINE; 834 if (!media_tracker.stream_opened) break; 835 status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid); 836 break; 837 case 'z': 838 if (media_tracker.avrcp_cid){ 839 avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t)); 840 } 841 printf("%c - Play mod.\n", cmd); 842 data_source = STREAM_MOD; 843 if (!media_tracker.stream_opened) break; 844 status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid); 845 break; 846 847 case 'p': 848 if (!media_tracker.stream_opened) break; 849 printf("%c - Pause stream.\n", cmd); 850 status = a2dp_source_pause_stream(media_tracker.a2dp_cid, media_tracker.local_seid); 851 break; 852 853 case 'w': 854 if (!media_tracker.stream_opened) break; 855 if (play_info.status == AVRCP_PLAYBACK_STATUS_PLAYING){ 856 printf("Stream cannot be reconfigured while playing, please pause stream first\n"); 857 break; 858 } 859 printf("%c - Reconfigure for 44100 Hz.\n", cmd); 860 status = a2dp_source_reconfigure_stream_sampling_frequency(media_tracker.a2dp_cid, 44100); 861 break; 862 863 case 'e': 864 if (!media_tracker.stream_opened) break; 865 if (play_info.status == AVRCP_PLAYBACK_STATUS_PLAYING){ 866 printf("Stream cannot be reconfigured while playing, please pause stream first\n"); 867 break; 868 } 869 printf("%c - Reconfigure for 48000 Hz.\n", cmd); 870 status = a2dp_source_reconfigure_stream_sampling_frequency(media_tracker.a2dp_cid, 48000); 871 break; 872 873 default: 874 show_usage(); 875 return; 876 } 877 if (status != ERROR_CODE_SUCCESS){ 878 printf("Could not perform command \'%c\', status 0x%2x\n", cmd, status); 879 } 880 } 881 #endif 882 883 884 int btstack_main(int argc, const char * argv[]); 885 int btstack_main(int argc, const char * argv[]){ 886 (void)argc; 887 (void)argv; 888 889 int err = a2dp_source_and_avrcp_services_init(); 890 if (err) return err; 891 // turn on! 892 hci_power_control(HCI_POWER_ON); 893 return 0; 894 } 895 /* EXAMPLE_END */ 896