1 /* 2 * Copyright (C) 2022 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__ "le_audio_broadcast_source.c" 39 40 /* 41 * LE Audio Broadcast Source 42 */ 43 44 #include <stdint.h> 45 #include <stdio.h> 46 #include <string.h> 47 #include <btstack_debug.h> 48 49 #include "bluetooth_data_types.h" 50 #include "btstack_stdin.h" 51 #include "btstack_event.h" 52 #include "btstack_run_loop.h" 53 #include "gap.h" 54 #include "hci.h" 55 #include "hci_cmd.h" 56 #include "hci_dump.h" 57 #include "btstack_lc3.h" 58 #include "btstack_lc3_google.h" 59 60 #include "hxcmod.h" 61 #include "mods/mod.h" 62 63 // PTS mode 64 // #define PTS_MODE 65 66 // Count mode - send packet count as test data for manual analysis 67 // #define COUNT_MODE 68 69 // create audio based on timer instead of num completed packets 70 // #define GENERATE_AUDIO_WITH_TIMER 71 72 // max config 73 #define MAX_NUM_BIS 2 74 #define MAX_SAMPLES_PER_FRAME 480 75 76 static const uint8_t adv_sid = 0; 77 78 static le_advertising_set_t le_advertising_set; 79 80 static const le_extended_advertising_parameters_t extended_params = { 81 .advertising_event_properties = 0, 82 .primary_advertising_interval_min = 0x4b0, // 750 ms 83 .primary_advertising_interval_max = 0x4b0, // 750 ms 84 .primary_advertising_channel_map = 7, 85 .own_address_type = 0, 86 .peer_address_type = 0, 87 .peer_address = 0, 88 .advertising_filter_policy = 0, 89 .advertising_tx_power = 10, // 10 dBm 90 .primary_advertising_phy = 1, // LE 1M PHY 91 .secondary_advertising_max_skip = 0, 92 .secondary_advertising_phy = 1, // LE 1M PHY 93 .advertising_sid = adv_sid, 94 .scan_request_notification_enable = 0, 95 }; 96 97 static const uint8_t extended_adv_data[] = { 98 // 16 bit service data, ORG_BLUETOOTH_SERVICE_BASIC_AUDIO_ANNOUNCEMENT_SERVICE, Broadcast ID 99 6, BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID, 0x52, 0x18, 0x30, 0x5d, 0x9b, 100 // name 101 #ifdef PTS_MODE 102 7, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'P', 'T', 'S', '-', 'x', 'x' 103 #elif defined(COUNT_MODE) 104 6, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'C', 'O', 'U', 'N', 'T' 105 #else 106 7, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'S', 'o', 'u', 'r', 'c', 'e' 107 #endif 108 }; 109 110 static const le_periodic_advertising_parameters_t periodic_params = { 111 .periodic_advertising_interval_min = 0x258, // 375 ms 112 .periodic_advertising_interval_max = 0x258, // 375 ms 113 .periodic_advertising_properties = 0 114 }; 115 116 static uint8_t periodic_adv_data_1[] = { 117 // 16 bit service data 118 37, BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID, 119 // Level 1 - BIG Parameters (common to all BISes) 120 0x51, 0x18, // Basic Audio Announcement Service UUID 121 0x28, 0x00, 0x00, // Presentation Delay 3 122 0x01, // Num_Subgroups 123 // Level 2 - BIS Subgroup Parameters (common parameters for subgroups of BISes) 124 // offset 8 125 0x01, // The number of BISes in this subgroup 126 0x06, 0x00, 0x00, 0x00, 0x00, // 0x06 = LC3, vendor id + codec id = 0 127 10, // Codec_Specific_Configuration_Length[i] 128 // Codec_Specific_Configuration[i] = 8_2 129 // offset 15 130 0x02, 0x01, 0x01, // Sampling frequency 0x01 = 0x01 / 8 kHz 131 0x02, 0x02, 0x01, // Frame Duration 0x02 = 0x01 / 10 ms 132 0x03, 0x04, 0x1E, 0x00, // Octets per Frame 0x04 = 0x1e / 30 133 4, // Metadata_Length[i] 134 0x03, 0x02, 0x04, 0x00, // Metadata[i] 135 // Level 3 - Specific BIS Parameters (if required, for individual BISes) 136 0x01, // BIS_index[i[k]] 137 6, // Codec_Specific_Configuration_Length[i[k]] 138 0x05, 0x03, 0x01, 0x00, 0x00, 0x00 // Codec_Specific_Configuration[i[k]] 139 }; 140 141 static uint8_t periodic_adv_data_2[] = { 142 // 16 bit service data 143 37+8, BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID, 144 // Level 1 - BIG Parameters (common to all BISes) 145 0x51, 0x18, // Basic Audio Announcement Service UUID 146 0x28, 0x00, 0x00, // Presentation Delay 3 147 0x01, // Num_Subgroups 148 // Level 2 - BIS Subgroup Parameters (common parameters for subgroups of BISes) 149 // offset 8 150 0x02, // The number of BISes in this subgroup 151 0x06, 0x00, 0x00, 0x00, 0x00, // 0x06 = LC3, vendor id + codec id = 0 152 10, // Codec_Specific_Configuration_Length[i] 153 // Codec_Specific_Configuration[0] = 8_2 154 // offset 15 155 0x02, 0x01, 0x01, // Sampling frequency 0x01 = 0x01 / 8 kHz 156 0x02, 0x02, 0x01, // Frame Duration 0x02 = 0x01 / 10 ms 157 0x03, 0x04, 0x1E, 0x00, // Octets per Frame 0x04 = 0x1e / 30 158 4, // Metadata_Length[i] 159 0x03, 0x02, 0x04, 0x00, // Metadata[0] 160 // Level 3 - Specific BIS Parameters (if required, for individual BISes) 161 0x01, // BIS_index[i[k]] 162 6, // Codec_Specific_Configuration_Length[i[k]] 163 0x05, 0x03, 0x01, 0x00, 0x00, 0x00, // Codec_Specific_Configuration[i[k]] 164 // Level 3 - Specific BIS Parameters (if required, for individual BISes) 165 0x02, // BIS_index[i[k]] 166 6, // Codec_Specific_Configuration_Length[i[k]] 167 0x05, 0x03, 0x02, 0x00, 0x00, 0x00 // Codec_Specific_Configuration[i[k]] 168 }; 169 170 // input signal: pre-computed int16 sine wave, 96000 Hz at 300 Hz 171 static const int16_t sine_int16[] = { 172 0, 643, 1286, 1929, 2571, 3212, 3851, 4489, 5126, 5760, 173 6393, 7022, 7649, 8273, 8894, 9512, 10126, 10735, 11341, 11943, 174 12539, 13131, 13718, 14300, 14876, 15446, 16011, 16569, 17121, 17666, 175 18204, 18736, 19260, 19777, 20286, 20787, 21280, 21766, 22242, 22710, 176 23170, 23620, 24062, 24494, 24916, 25329, 25732, 26126, 26509, 26882, 177 27245, 27597, 27938, 28269, 28589, 28898, 29196, 29482, 29757, 30021, 178 30273, 30513, 30742, 30958, 31163, 31356, 31537, 31705, 31862, 32006, 179 32137, 32257, 32364, 32458, 32540, 32609, 32666, 32710, 32742, 32761, 180 32767, 32761, 32742, 32710, 32666, 32609, 32540, 32458, 32364, 32257, 181 32137, 32006, 31862, 31705, 31537, 31356, 31163, 30958, 30742, 30513, 182 30273, 30021, 29757, 29482, 29196, 28898, 28589, 28269, 27938, 27597, 183 27245, 26882, 26509, 26126, 25732, 25329, 24916, 24494, 24062, 23620, 184 23170, 22710, 22242, 21766, 21280, 20787, 20286, 19777, 19260, 18736, 185 18204, 17666, 17121, 16569, 16011, 15446, 14876, 14300, 13718, 13131, 186 12539, 11943, 11341, 10735, 10126, 9512, 8894, 8273, 7649, 7022, 187 6393, 5760, 5126, 4489, 3851, 3212, 2571, 1929, 1286, 643, 188 0, -643, -1286, -1929, -2571, -3212, -3851, -4489, -5126, -5760, 189 -6393, -7022, -7649, -8273, -8894, -9512, -10126, -10735, -11341, -11943, 190 -12539, -13131, -13718, -14300, -14876, -15446, -16011, -16569, -17121, -17666, 191 -18204, -18736, -19260, -19777, -20286, -20787, -21280, -21766, -22242, -22710, 192 -23170, -23620, -24062, -24494, -24916, -25329, -25732, -26126, -26509, -26882, 193 -27245, -27597, -27938, -28269, -28589, -28898, -29196, -29482, -29757, -30021, 194 -30273, -30513, -30742, -30958, -31163, -31356, -31537, -31705, -31862, -32006, 195 -32137, -32257, -32364, -32458, -32540, -32609, -32666, -32710, -32742, -32761, 196 -32767, -32761, -32742, -32710, -32666, -32609, -32540, -32458, -32364, -32257, 197 -32137, -32006, -31862, -31705, -31537, -31356, -31163, -30958, -30742, -30513, 198 -30273, -30021, -29757, -29482, -29196, -28898, -28589, -28269, -27938, -27597, 199 -27245, -26882, -26509, -26126, -25732, -25329, -24916, -24494, -24062, -23620, 200 -23170, -22710, -22242, -21766, -21280, -20787, -20286, -19777, -19260, -18736, 201 -18204, -17666, -17121, -16569, -16011, -15446, -14876, -14300, -13718, -13131, 202 -12539, -11943, -11341, -10735, -10126, -9512, -8894, -8273, -7649, -7022, 203 -6393, -5760, -5126, -4489, -3851, -3212, -2571, -1929, -1286, -643, 204 }; 205 206 static bd_addr_t remote; 207 static const char * remote_addr_string = "00:1B:DC:08:E2:72"; 208 209 static btstack_packet_callback_registration_t hci_event_callback_registration; 210 211 static uint8_t adv_handle = 0; 212 static unsigned int next_bis_index; 213 static hci_con_handle_t bis_con_handles[MAX_NUM_BIS]; 214 static uint16_t packet_sequence_numbers[MAX_NUM_BIS]; 215 static uint8_t framed_pdus; 216 static bool bis_can_send[MAX_NUM_BIS]; 217 static bool bis_has_data[MAX_NUM_BIS]; 218 static uint8_t iso_frame_counter; 219 static uint16_t frame_duration_us; 220 221 // time stamping 222 #ifdef COUNT_MODE 223 #define MAX_PACKET_INTERVAL_BINS_MS 50 224 static uint32_t send_time_bins[MAX_PACKET_INTERVAL_BINS_MS]; 225 static uint32_t send_last_ms; 226 #endif 227 228 // time based sender 229 #ifdef GENERATE_AUDIO_WITH_TIMER 230 static uint32_t next_send_time_ms; 231 static uint32_t next_send_time_additional_us; 232 static btstack_timer_source_t send_timer; 233 #endif 234 235 // lc3 codec config 236 static uint32_t sampling_frequency_hz; 237 static btstack_lc3_frame_duration_t frame_duration; 238 static uint16_t number_samples_per_frame; 239 static uint16_t octets_per_frame; 240 static uint8_t num_bis = 1; 241 242 // lc3 encoder 243 static const btstack_lc3_encoder_t * lc3_encoder; 244 static btstack_lc3_encoder_google_t encoder_contexts[MAX_NUM_BIS]; 245 static int16_t pcm[MAX_NUM_BIS * MAX_SAMPLES_PER_FRAME]; 246 static uint32_t time_generation_ms; 247 248 // codec menu 249 static uint8_t menu_sampling_frequency; 250 static uint8_t menu_variant; 251 252 // mod player 253 static int hxcmod_initialized; 254 static modcontext mod_context; 255 static tracker_buffer_state trkbuf; 256 257 // sine generator 258 static uint8_t sine_step; 259 static uint16_t sine_phases[MAX_NUM_BIS]; 260 261 // audio producer 262 static enum { 263 AUDIO_SOURCE_SINE, 264 AUDIO_SOURCE_MODPLAYER 265 } audio_source = AUDIO_SOURCE_MODPLAYER; 266 267 static enum { 268 APP_IDLE, 269 APP_W4_PERIODIC_ENABLED, 270 APP_CREATE_BIG, 271 APP_W4_CREATE_BIG_COMPLETE, 272 APP_SET_ISO_PATH, 273 APP_STREAMING 274 } app_state = APP_IDLE; 275 276 // enumerate default codec configs 277 static struct { 278 uint32_t samplingrate_hz; 279 uint8_t samplingrate_index; 280 uint8_t num_variants; 281 struct { 282 const char * name; 283 btstack_lc3_frame_duration_t frame_duration; 284 uint16_t octets_per_frame; 285 } variants[6]; 286 } codec_configurations[] = { 287 { 288 8000, 0x01, 2, 289 { 290 { "8_1", BTSTACK_LC3_FRAME_DURATION_7500US, 26}, 291 { "8_2", BTSTACK_LC3_FRAME_DURATION_10000US, 30} 292 } 293 }, 294 { 295 16000, 0x03, 2, 296 { 297 { "16_1", BTSTACK_LC3_FRAME_DURATION_7500US, 30}, 298 { "16_2", BTSTACK_LC3_FRAME_DURATION_10000US, 40} 299 } 300 }, 301 { 302 24000, 0x05, 2, 303 { 304 { "24_1", BTSTACK_LC3_FRAME_DURATION_7500US, 45}, 305 { "24_2", BTSTACK_LC3_FRAME_DURATION_10000US, 60} 306 } 307 }, 308 { 309 32000, 0x06, 2, 310 { 311 { "32_1", BTSTACK_LC3_FRAME_DURATION_7500US, 60}, 312 { "32_2", BTSTACK_LC3_FRAME_DURATION_10000US, 80} 313 } 314 }, 315 { 316 44100, 0x07, 2, 317 { 318 { "441_1", BTSTACK_LC3_FRAME_DURATION_7500US, 97}, 319 { "441_2", BTSTACK_LC3_FRAME_DURATION_10000US, 130} 320 } 321 }, 322 { 323 48000, 0x08, 6, 324 { 325 { "48_1", BTSTACK_LC3_FRAME_DURATION_7500US, 75}, 326 { "48_2", BTSTACK_LC3_FRAME_DURATION_10000US, 100}, 327 { "48_3", BTSTACK_LC3_FRAME_DURATION_7500US, 90}, 328 { "48_4", BTSTACK_LC3_FRAME_DURATION_10000US, 120}, 329 { "48_5", BTSTACK_LC3_FRAME_DURATION_7500US, 117}, 330 { "48_6", BTSTACK_LC3_FRAME_DURATION_10000US, 155} 331 } 332 }, 333 }; 334 335 static void show_usage(void); 336 337 static void print_config(void) { 338 printf("Config '%s_%u': %u, %s ms, %u octets - %s\n", 339 codec_configurations[menu_sampling_frequency].variants[menu_variant].name, 340 num_bis, 341 codec_configurations[menu_sampling_frequency].samplingrate_hz, 342 codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10", 343 codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame, 344 audio_source == AUDIO_SOURCE_SINE ? "Sine" : "Modplayer"); 345 } 346 347 static void setup_lc3_encoder(void){ 348 uint8_t channel; 349 for (channel = 0 ; channel < num_bis ; channel++){ 350 btstack_lc3_encoder_google_t * context = &encoder_contexts[channel]; 351 lc3_encoder = btstack_lc3_encoder_google_init_instance(context); 352 lc3_encoder->configure(context, sampling_frequency_hz, frame_duration); 353 } 354 number_samples_per_frame = lc3_encoder->get_number_samples_per_frame(&encoder_contexts[0]); 355 btstack_assert(number_samples_per_frame <= MAX_SAMPLES_PER_FRAME); 356 printf("LC3 Encoder config: %u hz, frame duration %s ms, num samples %u, num octets %u\n", 357 sampling_frequency_hz, frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10", 358 number_samples_per_frame, octets_per_frame); 359 } 360 361 static void setup_mod_player(void){ 362 if (!hxcmod_initialized) { 363 hxcmod_initialized = hxcmod_init(&mod_context); 364 btstack_assert(hxcmod_initialized != 0); 365 } 366 hxcmod_unload(&mod_context); 367 hxcmod_setcfg(&mod_context, sampling_frequency_hz, 16, 1, 1, 1); 368 hxcmod_load(&mod_context, (void *) &mod_data, mod_len); 369 } 370 371 static void generate_audio(void){ 372 uint32_t start_ms = btstack_run_loop_get_time_ms(); 373 uint16_t sample; 374 switch (audio_source) { 375 case AUDIO_SOURCE_SINE: 376 // generate sine wave for all channels 377 for (sample = 0 ; sample < number_samples_per_frame ; sample++){ 378 uint8_t channel; 379 for (channel = 0; channel < num_bis; channel++) { 380 int16_t value = sine_int16[sine_phases[channel]] / 4; 381 pcm[sample * num_bis + channel] = value; 382 sine_phases[channel] += sine_step * (1+channel); // second channel, double frequency 383 if (sine_phases[channel] >= (sizeof(sine_int16) / sizeof(int16_t))) { 384 sine_phases[channel] = 0; 385 } 386 } 387 } 388 break; 389 case AUDIO_SOURCE_MODPLAYER: 390 // mod player configured for stereo 391 hxcmod_fillbuffer(&mod_context, (unsigned short *) pcm, number_samples_per_frame, &trkbuf); 392 if (num_bis == 1) { 393 // stereo -> mono 394 uint16_t i; 395 for (i=0;i<number_samples_per_frame;i++){ 396 pcm[i] = (pcm[2*i] / 2) + (pcm[2*i+1] / 2); 397 } 398 } 399 break; 400 default: 401 btstack_unreachable(); 402 break; 403 } 404 time_generation_ms = btstack_run_loop_get_time_ms() - start_ms; 405 iso_frame_counter++; 406 } 407 408 static void encode_and_send(uint8_t bis_index){ 409 410 #ifdef COUNT_MODE 411 if (bis_index == 0) { 412 uint32_t now = btstack_run_loop_get_time_ms(); 413 if (send_last_ms != 0) { 414 uint16_t send_interval_ms = now - send_last_ms; 415 if (send_interval_ms >= MAX_PACKET_INTERVAL_BINS_MS) { 416 printf("ERROR: send interval %u\n", send_interval_ms); 417 } else { 418 send_time_bins[send_interval_ms]++; 419 } 420 } 421 send_last_ms = now; 422 } 423 #endif 424 bool ok = hci_reserve_packet_buffer(); 425 btstack_assert(ok); 426 uint8_t * buffer = hci_get_outgoing_packet_buffer(); 427 // complete SDU, no TimeStamp 428 little_endian_store_16(buffer, 0, bis_con_handles[bis_index] | (2 << 12)); 429 // len 430 little_endian_store_16(buffer, 2, 0 + 4 + octets_per_frame); 431 // TimeStamp if TS flag is set 432 // packet seq nr 433 little_endian_store_16(buffer, 4, packet_sequence_numbers[bis_index]); 434 // iso sdu len 435 little_endian_store_16(buffer, 6, octets_per_frame); 436 #ifdef COUNT_MODE 437 // test data: bis_index, counter 438 buffer[8] = bis_index; 439 memset(&buffer[9], iso_frame_counter, octets_per_frame - 1); 440 #else 441 // encode as lc3 442 lc3_encoder->encode_signed_16(&encoder_contexts[bis_index], &pcm[bis_index], num_bis, &buffer[8], octets_per_frame); 443 #endif 444 // send 445 hci_send_iso_packet_buffer(4 + 0 + 4 + octets_per_frame); 446 447 if (((packet_sequence_numbers[bis_index] & 0x7f) == 0) && (bis_index == 0)) { 448 printf("Encoding time: %u\n", time_generation_ms); 449 } 450 if ((packet_sequence_numbers[bis_index] & 0x7c) == 0){ 451 printf("%04x %10u %u ", packet_sequence_numbers[bis_index], btstack_run_loop_get_time_ms(), bis_index); 452 printf_hexdump(&buffer[8], octets_per_frame); 453 } 454 455 packet_sequence_numbers[bis_index]++; 456 } 457 458 static void try_send(void){ 459 bool all_can_send = true; 460 uint8_t i; 461 for (i=0; i<num_bis;i++) { 462 all_can_send &= bis_can_send[i]; 463 } 464 #ifdef PTS_MODE 465 static uint8_t next_sender; 466 // PTS 8.2 sends a packet after the previous one was received -> it sends at half speed for stereo configuration 467 if (all_can_send) { 468 if (next_sender == 0) { 469 generate_audio(); 470 } 471 bis_can_send[next_sender] = false; 472 encode_and_send(next_sender); 473 next_sender = (num_bis - 1) - next_sender; 474 } 475 #else 476 #ifdef GENERATE_AUDIO_WITH_TIMER 477 for (i=0;i<num_bis;i++){ 478 if (hci_is_packet_buffer_reserved()) return; 479 if (bis_has_data[i]){ 480 bis_can_send[i] = false; 481 bis_has_data[i] = false; 482 encode_and_send(i); 483 return; 484 } 485 } 486 #else 487 // check if next audio frame should be produced and send 488 if (all_can_send){ 489 generate_audio(); 490 for (i=0; i<num_bis;i++) { 491 bis_has_data[i] = true; 492 } 493 } 494 495 for (i=0;i<num_bis;i++){ 496 if (hci_is_packet_buffer_reserved()) return; 497 if (bis_can_send[i] && bis_has_data[i]){ 498 bis_can_send[i] = false; 499 bis_has_data[i] = false; 500 encode_and_send(i); 501 return; 502 } 503 } 504 #endif 505 #endif 506 } 507 508 #ifdef GENERATE_AUDIO_WITH_TIMER 509 static void generate_audio_timer_handler(btstack_timer_source_t *ts){ 510 511 generate_audio(); 512 513 uint8_t i; 514 for (i=0; i<num_bis;i++) { 515 bis_has_data[i] = true; 516 } 517 518 // next send time based on frame_duration_us 519 next_send_time_additional_us += frame_duration_us % 1000; 520 if (next_send_time_additional_us > 1000){ 521 next_send_time_ms++; 522 next_send_time_additional_us -= 1000; 523 } 524 next_send_time_ms += frame_duration_us / 1000; 525 526 uint32_t now = btstack_run_loop_get_time_ms(); 527 btstack_run_loop_set_timer(&send_timer, next_send_time_ms - now); 528 btstack_run_loop_add_timer(&send_timer); 529 530 try_send(); 531 } 532 #endif 533 534 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 535 UNUSED(channel); 536 if (packet_type != HCI_EVENT_PACKET) return; 537 538 switch (packet[0]) { 539 case BTSTACK_EVENT_STATE: 540 switch(btstack_event_state_get_state(packet)) { 541 case HCI_STATE_WORKING: 542 show_usage(); 543 printf("Please select sample frequency and variation, then start broadcast\n"); 544 break; 545 case HCI_STATE_OFF: 546 printf("Goodbye\n"); 547 exit(0); 548 break; 549 default: 550 break; 551 } 552 break; 553 case HCI_EVENT_COMMAND_COMPLETE: 554 switch (hci_event_command_complete_get_command_opcode(packet)){ 555 case HCI_OPCODE_HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE: 556 if (app_state != APP_W4_PERIODIC_ENABLED) break; 557 app_state = APP_CREATE_BIG; 558 break; 559 case HCI_OPCODE_HCI_LE_SETUP_ISO_DATA_PATH: 560 next_bis_index++; 561 if (next_bis_index == num_bis){ 562 printf("%u ISO path(s) set up\n", num_bis); 563 // ready to send 564 uint8_t i; 565 for (i=0;i<num_bis;i++) { 566 bis_can_send[i] = true; 567 } 568 app_state = APP_STREAMING; 569 // 570 #ifdef GENERATE_AUDIO_WITH_TIMER 571 btstack_run_loop_set_timer_handler(&send_timer, &generate_audio_timer_handler); 572 uint32_t next_send_time_ms = btstack_run_loop_get_time_ms() + 10; 573 uint32_t now = btstack_run_loop_get_time_ms(); 574 btstack_run_loop_set_timer(&send_timer, next_send_time_ms - now); 575 btstack_run_loop_add_timer(&send_timer); 576 #endif 577 } 578 break; 579 } 580 break; 581 case HCI_EVENT_LE_META: 582 switch(hci_event_le_meta_get_subevent_code(packet)){ 583 case HCI_SUBEVENT_LE_CREATE_BIG_COMPLETE: 584 if (app_state == APP_W4_CREATE_BIG_COMPLETE){ 585 uint8_t i; 586 printf("BIS Connection Handles: "); 587 for (i=0;i<num_bis;i++){ 588 bis_con_handles[i] = little_endian_read_16(packet, 21 + 2*i); 589 printf("0x%04x ", bis_con_handles[i]); 590 } 591 printf("\n"); 592 next_bis_index = 0; 593 app_state = APP_SET_ISO_PATH; 594 printf("Start streaming\n"); 595 } 596 break; 597 default: 598 break; 599 } 600 break; 601 case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS: 602 if (size >= 3){ 603 uint16_t num_handles = packet[2]; 604 if (size != (3u + num_handles * 4u)) break; 605 uint16_t offset = 3; 606 uint16_t i; 607 for (i=0; i<num_handles;i++) { 608 hci_con_handle_t handle = little_endian_read_16(packet, offset) & 0x0fffu; 609 offset += 2u; 610 uint16_t num_packets = little_endian_read_16(packet, offset); 611 offset += 2u; 612 uint8_t j; 613 for (j=0 ; j<num_bis ; j++){ 614 if (handle == bis_con_handles[j]){ 615 // allow to send 616 bis_can_send[j] = true; 617 } 618 } 619 } 620 } 621 break; 622 default: 623 break; 624 } 625 626 const uint8_t broadcast_code[16] = { 0 }; 627 switch(app_state){ 628 case APP_CREATE_BIG: 629 if (hci_can_send_command_packet_now()) { 630 app_state = APP_W4_CREATE_BIG_COMPLETE; 631 if (sampling_frequency_hz == 44100){ 632 framed_pdus = 1; 633 // same config as for 48k -> frame is longer by 48/44.1 634 frame_duration_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 8163 : 10884; 635 } else { 636 framed_pdus = 0; 637 frame_duration_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 7500 : 10000; 638 } 639 hci_send_cmd(&hci_le_create_big, 0, adv_handle, num_bis, frame_duration_us, octets_per_frame, 0x1F, 2, 2, 0, framed_pdus, 0, broadcast_code); 640 } 641 break; 642 case APP_SET_ISO_PATH: 643 if (!hci_can_send_command_packet_now()) break; 644 hci_send_cmd(&hci_le_setup_iso_data_path, bis_con_handles[next_bis_index], 0, 0, 0, 0, 0, 0, 0, NULL); 645 break; 646 default: 647 break; 648 } 649 650 try_send(); 651 } 652 653 static void show_usage(void){ 654 printf("\n--- LE Audio Broadcast Source Test Console ---\n"); 655 print_config(); 656 printf("---\n"); 657 printf("c - toggle channels\n"); 658 printf("f - next sampling frequency\n"); 659 printf("v - next codec variant\n"); 660 printf("t - toggle sine / modplayer\n"); 661 printf("s - start broadcast\n"); 662 printf("x - shutdown\n"); 663 printf("---\n"); 664 } 665 666 static void stdin_process(char c){ 667 switch (c){ 668 case 'c': 669 if (app_state != APP_IDLE){ 670 printf("Codec configuration can only be changed in idle state\n"); 671 break; 672 } 673 num_bis = 3 - num_bis; 674 print_config(); 675 break; 676 case 'f': 677 if (app_state != APP_IDLE){ 678 printf("Codec configuration can only be changed in idle state\n"); 679 break; 680 } 681 menu_sampling_frequency++; 682 if (menu_sampling_frequency >= 6){ 683 menu_sampling_frequency = 0; 684 } 685 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 686 menu_variant = 0; 687 } 688 print_config(); 689 break; 690 case 'v': 691 if (app_state != APP_IDLE){ 692 printf("Codec configuration can only be changed in idle state\n"); 693 break; 694 } 695 menu_variant++; 696 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 697 menu_variant = 0; 698 } 699 print_config(); 700 break; 701 case 'x': 702 #ifdef COUNT_MODE 703 printf("Send statistic:\n"); 704 { 705 uint16_t i; 706 for (i=0;i<MAX_PACKET_INTERVAL_BINS_MS;i++){ 707 printf("%2u: %5u\n", i, send_time_bins[i]); 708 } 709 } 710 #endif 711 printf("Shutdown...\n"); 712 hci_power_control(HCI_POWER_OFF); 713 break; 714 case 's': 715 if (app_state != APP_IDLE){ 716 printf("Cannot start broadcast - not in idle state\n"); 717 break; 718 } 719 // use values from table 720 sampling_frequency_hz = codec_configurations[menu_sampling_frequency].samplingrate_hz; 721 octets_per_frame = codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame; 722 frame_duration = codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration; 723 724 // get num samples per frame 725 setup_lc3_encoder(); 726 727 // update BASEs 728 periodic_adv_data_1[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 729 periodic_adv_data_1[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 730 little_endian_store_16(periodic_adv_data_1, 23, octets_per_frame); 731 732 periodic_adv_data_2[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 733 periodic_adv_data_2[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 734 little_endian_store_16(periodic_adv_data_2, 23, octets_per_frame); 735 736 // setup mod player 737 setup_mod_player(); 738 739 // setup sine generator 740 if (sampling_frequency_hz == 44100){ 741 sine_step = 2; 742 } else { 743 sine_step = 96000 / sampling_frequency_hz; 744 } 745 746 // setup 747 app_state = APP_W4_PERIODIC_ENABLED; 748 gap_extended_advertising_setup(&le_advertising_set, &extended_params, &adv_handle); 749 gap_extended_advertising_set_adv_data(adv_handle, sizeof(extended_adv_data), extended_adv_data); 750 gap_periodic_advertising_set_params(adv_handle, &periodic_params); 751 switch(num_bis){ 752 case 1: 753 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_1), periodic_adv_data_1); 754 printf("BASE: "); 755 printf_hexdump(periodic_adv_data_1, sizeof(periodic_adv_data_1)); 756 break; 757 case 2: 758 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_2), periodic_adv_data_2); 759 printf("BASE: "); 760 printf_hexdump(periodic_adv_data_2, sizeof(periodic_adv_data_2)); 761 break; 762 default: 763 btstack_unreachable(); 764 break; 765 } 766 gap_periodic_advertising_start(adv_handle, 0); 767 gap_extended_advertising_start(adv_handle, 0, 0); 768 break; 769 case 't': 770 audio_source = 1 - audio_source; 771 print_config(); 772 break; 773 case '\n': 774 case '\r': 775 break; 776 default: 777 show_usage(); 778 break; 779 } 780 } 781 782 int btstack_main(int argc, const char * argv[]); 783 int btstack_main(int argc, const char * argv[]){ 784 (void) argv; 785 (void) argc; 786 787 // register for HCI events 788 hci_event_callback_registration.callback = &packet_handler; 789 hci_add_event_handler(&hci_event_callback_registration); 790 791 // turn on! 792 hci_power_control(HCI_POWER_ON); 793 794 btstack_stdin_setup(stdin_process); 795 return 0; 796 } 797