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 static le_audio_big_t big_storage; 222 static le_audio_big_params_t big_params; 223 224 // time stamping 225 #ifdef COUNT_MODE 226 #define MAX_PACKET_INTERVAL_BINS_MS 50 227 static uint32_t send_time_bins[MAX_PACKET_INTERVAL_BINS_MS]; 228 static uint32_t send_last_ms; 229 #endif 230 231 // time based sender 232 #ifdef GENERATE_AUDIO_WITH_TIMER 233 static uint32_t next_send_time_ms; 234 static uint32_t next_send_time_additional_us; 235 static btstack_timer_source_t send_timer; 236 #endif 237 238 // lc3 codec config 239 static uint32_t sampling_frequency_hz; 240 static btstack_lc3_frame_duration_t frame_duration; 241 static uint16_t number_samples_per_frame; 242 static uint16_t octets_per_frame; 243 static uint8_t num_bis = 1; 244 245 // lc3 encoder 246 static const btstack_lc3_encoder_t * lc3_encoder; 247 static btstack_lc3_encoder_google_t encoder_contexts[MAX_NUM_BIS]; 248 static int16_t pcm[MAX_NUM_BIS * MAX_SAMPLES_PER_FRAME]; 249 static uint32_t time_generation_ms; 250 251 // codec menu 252 static uint8_t menu_sampling_frequency; 253 static uint8_t menu_variant; 254 255 // mod player 256 static int hxcmod_initialized; 257 static modcontext mod_context; 258 static tracker_buffer_state trkbuf; 259 260 // sine generator 261 static uint8_t sine_step; 262 static uint16_t sine_phases[MAX_NUM_BIS]; 263 264 // audio producer 265 static enum { 266 AUDIO_SOURCE_SINE, 267 AUDIO_SOURCE_MODPLAYER 268 } audio_source = AUDIO_SOURCE_MODPLAYER; 269 270 static enum { 271 APP_IDLE, 272 APP_W4_PERIODIC_ENABLED, 273 APP_W4_CREATE_BIG_COMPLETE, 274 APP_STREAMING 275 } app_state = APP_IDLE; 276 277 // enumerate default codec configs 278 static struct { 279 uint32_t samplingrate_hz; 280 uint8_t samplingrate_index; 281 uint8_t num_variants; 282 struct { 283 const char * name; 284 btstack_lc3_frame_duration_t frame_duration; 285 uint16_t octets_per_frame; 286 } variants[6]; 287 } codec_configurations[] = { 288 { 289 8000, 0x01, 2, 290 { 291 { "8_1", BTSTACK_LC3_FRAME_DURATION_7500US, 26}, 292 { "8_2", BTSTACK_LC3_FRAME_DURATION_10000US, 30} 293 } 294 }, 295 { 296 16000, 0x03, 2, 297 { 298 { "16_1", BTSTACK_LC3_FRAME_DURATION_7500US, 30}, 299 { "16_2", BTSTACK_LC3_FRAME_DURATION_10000US, 40} 300 } 301 }, 302 { 303 24000, 0x05, 2, 304 { 305 { "24_1", BTSTACK_LC3_FRAME_DURATION_7500US, 45}, 306 { "24_2", BTSTACK_LC3_FRAME_DURATION_10000US, 60} 307 } 308 }, 309 { 310 32000, 0x06, 2, 311 { 312 { "32_1", BTSTACK_LC3_FRAME_DURATION_7500US, 60}, 313 { "32_2", BTSTACK_LC3_FRAME_DURATION_10000US, 80} 314 } 315 }, 316 { 317 44100, 0x07, 2, 318 { 319 { "441_1", BTSTACK_LC3_FRAME_DURATION_7500US, 97}, 320 { "441_2", BTSTACK_LC3_FRAME_DURATION_10000US, 130} 321 } 322 }, 323 { 324 48000, 0x08, 6, 325 { 326 { "48_1", BTSTACK_LC3_FRAME_DURATION_7500US, 75}, 327 { "48_2", BTSTACK_LC3_FRAME_DURATION_10000US, 100}, 328 { "48_3", BTSTACK_LC3_FRAME_DURATION_7500US, 90}, 329 { "48_4", BTSTACK_LC3_FRAME_DURATION_10000US, 120}, 330 { "48_5", BTSTACK_LC3_FRAME_DURATION_7500US, 117}, 331 { "48_6", BTSTACK_LC3_FRAME_DURATION_10000US, 155} 332 } 333 }, 334 }; 335 336 static void show_usage(void); 337 338 static void print_config(void) { 339 printf("Config '%s_%u': %u, %s ms, %u octets - %s\n", 340 codec_configurations[menu_sampling_frequency].variants[menu_variant].name, 341 num_bis, 342 codec_configurations[menu_sampling_frequency].samplingrate_hz, 343 codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10", 344 codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame, 345 audio_source == AUDIO_SOURCE_SINE ? "Sine" : "Modplayer"); 346 } 347 348 static void setup_lc3_encoder(void){ 349 uint8_t channel; 350 for (channel = 0 ; channel < num_bis ; channel++){ 351 btstack_lc3_encoder_google_t * context = &encoder_contexts[channel]; 352 lc3_encoder = btstack_lc3_encoder_google_init_instance(context); 353 lc3_encoder->configure(context, sampling_frequency_hz, frame_duration); 354 } 355 number_samples_per_frame = lc3_encoder->get_number_samples_per_frame(&encoder_contexts[0]); 356 btstack_assert(number_samples_per_frame <= MAX_SAMPLES_PER_FRAME); 357 printf("LC3 Encoder config: %u hz, frame duration %s ms, num samples %u, num octets %u\n", 358 sampling_frequency_hz, frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10", 359 number_samples_per_frame, octets_per_frame); 360 } 361 362 static void setup_mod_player(void){ 363 if (!hxcmod_initialized) { 364 hxcmod_initialized = hxcmod_init(&mod_context); 365 btstack_assert(hxcmod_initialized != 0); 366 } 367 hxcmod_unload(&mod_context); 368 hxcmod_setcfg(&mod_context, sampling_frequency_hz, 16, 1, 1, 1); 369 hxcmod_load(&mod_context, (void *) &mod_data, mod_len); 370 } 371 372 static void generate_audio(void){ 373 uint32_t start_ms = btstack_run_loop_get_time_ms(); 374 uint16_t sample; 375 switch (audio_source) { 376 case AUDIO_SOURCE_SINE: 377 // generate sine wave for all channels 378 for (sample = 0 ; sample < number_samples_per_frame ; sample++){ 379 uint8_t channel; 380 for (channel = 0; channel < num_bis; channel++) { 381 int16_t value = sine_int16[sine_phases[channel]] / 4; 382 pcm[sample * num_bis + channel] = value; 383 sine_phases[channel] += sine_step * (1+channel); // second channel, double frequency 384 if (sine_phases[channel] >= (sizeof(sine_int16) / sizeof(int16_t))) { 385 sine_phases[channel] = 0; 386 } 387 } 388 } 389 break; 390 case AUDIO_SOURCE_MODPLAYER: 391 // mod player configured for stereo 392 hxcmod_fillbuffer(&mod_context, (unsigned short *) pcm, number_samples_per_frame, &trkbuf); 393 if (num_bis == 1) { 394 // stereo -> mono 395 uint16_t i; 396 for (i=0;i<number_samples_per_frame;i++){ 397 pcm[i] = (pcm[2*i] / 2) + (pcm[2*i+1] / 2); 398 } 399 } 400 break; 401 default: 402 btstack_unreachable(); 403 break; 404 } 405 time_generation_ms = btstack_run_loop_get_time_ms() - start_ms; 406 iso_frame_counter++; 407 } 408 409 static void encode_and_send(uint8_t bis_index){ 410 411 #ifdef COUNT_MODE 412 if (bis_index == 0) { 413 uint32_t now = btstack_run_loop_get_time_ms(); 414 if (send_last_ms != 0) { 415 uint16_t send_interval_ms = now - send_last_ms; 416 if (send_interval_ms >= MAX_PACKET_INTERVAL_BINS_MS) { 417 printf("ERROR: send interval %u\n", send_interval_ms); 418 } else { 419 send_time_bins[send_interval_ms]++; 420 } 421 } 422 send_last_ms = now; 423 } 424 #endif 425 bool ok = hci_reserve_packet_buffer(); 426 btstack_assert(ok); 427 uint8_t * buffer = hci_get_outgoing_packet_buffer(); 428 // complete SDU, no TimeStamp 429 little_endian_store_16(buffer, 0, bis_con_handles[bis_index] | (2 << 12)); 430 // len 431 little_endian_store_16(buffer, 2, 0 + 4 + octets_per_frame); 432 // TimeStamp if TS flag is set 433 // packet seq nr 434 little_endian_store_16(buffer, 4, packet_sequence_numbers[bis_index]); 435 // iso sdu len 436 little_endian_store_16(buffer, 6, octets_per_frame); 437 #ifdef COUNT_MODE 438 // test data: bis_index, counter 439 buffer[8] = bis_index; 440 memset(&buffer[9], iso_frame_counter, octets_per_frame - 1); 441 #else 442 // encode as lc3 443 lc3_encoder->encode_signed_16(&encoder_contexts[bis_index], &pcm[bis_index], num_bis, &buffer[8], octets_per_frame); 444 #endif 445 // send 446 hci_send_iso_packet_buffer(4 + 0 + 4 + octets_per_frame); 447 448 if (((packet_sequence_numbers[bis_index] & 0x7f) == 0) && (bis_index == 0)) { 449 printf("Encoding time: %u\n", time_generation_ms); 450 } 451 if ((packet_sequence_numbers[bis_index] & 0x7c) == 0){ 452 printf("%04x %10u %u ", packet_sequence_numbers[bis_index], btstack_run_loop_get_time_ms(), bis_index); 453 printf_hexdump(&buffer[8], octets_per_frame); 454 } 455 456 packet_sequence_numbers[bis_index]++; 457 } 458 459 static void try_send(void){ 460 bool all_can_send = true; 461 uint8_t i; 462 for (i=0; i<num_bis;i++) { 463 all_can_send &= bis_can_send[i]; 464 } 465 #ifdef PTS_MODE 466 static uint8_t next_sender; 467 // PTS 8.2 sends a packet after the previous one was received -> it sends at half speed for stereo configuration 468 if (all_can_send) { 469 if (next_sender == 0) { 470 generate_audio(); 471 } 472 bis_can_send[next_sender] = false; 473 encode_and_send(next_sender); 474 next_sender = (num_bis - 1) - next_sender; 475 } 476 #else 477 #ifdef GENERATE_AUDIO_WITH_TIMER 478 for (i=0;i<num_bis;i++){ 479 if (hci_is_packet_buffer_reserved()) return; 480 if (bis_has_data[i]){ 481 bis_can_send[i] = false; 482 bis_has_data[i] = false; 483 encode_and_send(i); 484 return; 485 } 486 } 487 #else 488 // check if next audio frame should be produced and send 489 if (all_can_send){ 490 generate_audio(); 491 for (i=0; i<num_bis;i++) { 492 bis_has_data[i] = true; 493 } 494 } 495 496 for (i=0;i<num_bis;i++){ 497 if (hci_is_packet_buffer_reserved()) return; 498 if (bis_can_send[i] && bis_has_data[i]){ 499 bis_can_send[i] = false; 500 bis_has_data[i] = false; 501 encode_and_send(i); 502 return; 503 } 504 } 505 #endif 506 #endif 507 } 508 509 #ifdef GENERATE_AUDIO_WITH_TIMER 510 static void generate_audio_timer_handler(btstack_timer_source_t *ts){ 511 512 generate_audio(); 513 514 uint8_t i; 515 for (i=0; i<num_bis;i++) { 516 bis_has_data[i] = true; 517 } 518 519 // next send time based on frame_duration_us 520 next_send_time_additional_us += frame_duration_us % 1000; 521 if (next_send_time_additional_us > 1000){ 522 next_send_time_ms++; 523 next_send_time_additional_us -= 1000; 524 } 525 next_send_time_ms += frame_duration_us / 1000; 526 527 uint32_t now = btstack_run_loop_get_time_ms(); 528 btstack_run_loop_set_timer(&send_timer, next_send_time_ms - now); 529 btstack_run_loop_add_timer(&send_timer); 530 531 try_send(); 532 } 533 #endif 534 535 static void create_big(void){ 536 // Create BIG 537 big_params.big_handle = 0; 538 big_params.advertising_handle = adv_handle; 539 big_params.num_bis = num_bis; 540 big_params.max_sdu = octets_per_frame; 541 big_params.max_transport_latency_ms = 31; 542 big_params.rtn = 2; 543 big_params.phy = 2; 544 big_params.packing = 0; 545 big_params.encryption = 0; 546 memset(big_params.broadcast_code, 0, 16); 547 if (sampling_frequency_hz == 44100){ 548 // same config as for 48k -> frame is longer by 48/44.1 549 big_params.sdu_interval_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 8163 : 10884; 550 big_params.framing = 1; 551 } else { 552 big_params.sdu_interval_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 7500 : 10000; 553 big_params.framing = 0; 554 } 555 app_state = APP_W4_CREATE_BIG_COMPLETE; 556 gap_big_create(&big_storage, &big_params); 557 } 558 559 static void ready_to_send(void){ 560 // ready to send 561 uint8_t i; 562 for (i=0;i<num_bis;i++) { 563 bis_can_send[i] = true; 564 } 565 app_state = APP_STREAMING; 566 // 567 #ifdef GENERATE_AUDIO_WITH_TIMER 568 btstack_run_loop_set_timer_handler(&send_timer, &generate_audio_timer_handler); 569 uint32_t next_send_time_ms = btstack_run_loop_get_time_ms() + 10; 570 uint32_t now = btstack_run_loop_get_time_ms(); 571 btstack_run_loop_set_timer(&send_timer, next_send_time_ms - now); 572 btstack_run_loop_add_timer(&send_timer); 573 #endif 574 } 575 576 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 577 UNUSED(channel); 578 if (packet_type != HCI_EVENT_PACKET) return; 579 580 switch (packet[0]) { 581 case BTSTACK_EVENT_STATE: 582 switch(btstack_event_state_get_state(packet)) { 583 case HCI_STATE_WORKING: 584 show_usage(); 585 printf("Please select sample frequency and variation, then start broadcast\n"); 586 break; 587 case HCI_STATE_OFF: 588 printf("Goodbye\n"); 589 exit(0); 590 break; 591 default: 592 break; 593 } 594 break; 595 case HCI_EVENT_COMMAND_COMPLETE: 596 switch (hci_event_command_complete_get_command_opcode(packet)){ 597 case HCI_OPCODE_HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE: 598 if (app_state != APP_W4_PERIODIC_ENABLED) break; 599 create_big(); 600 break; 601 default: 602 break; 603 } 604 break; 605 case HCI_EVENT_META_GAP: 606 switch (hci_event_gap_meta_get_subevent_code(packet)){ 607 case GAP_SUBEVENT_BIG_CREATED: { 608 printf("BIG Created with BIS Connection handles: \n"); 609 uint8_t i; 610 for (i=0;i<num_bis;i++){ 611 bis_con_handles[i] = gap_subevent_big_created_get_bis_con_handles(packet, i); 612 printf("0x%04x ", bis_con_handles[i]); 613 } 614 ready_to_send(); 615 app_state = APP_STREAMING; 616 printf("Start streaming\n"); 617 break; 618 } 619 default: 620 break; 621 } 622 break; 623 case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS: 624 if (size >= 3){ 625 uint16_t num_handles = packet[2]; 626 if (size != (3u + num_handles * 4u)) break; 627 uint16_t offset = 3; 628 uint16_t i; 629 for (i=0; i<num_handles;i++) { 630 hci_con_handle_t handle = little_endian_read_16(packet, offset) & 0x0fffu; 631 offset += 2u; 632 uint16_t num_packets = little_endian_read_16(packet, offset); 633 offset += 2u; 634 uint8_t j; 635 for (j=0 ; j<num_bis ; j++){ 636 if (handle == bis_con_handles[j]){ 637 // allow to send 638 bis_can_send[j] = true; 639 } 640 } 641 } 642 } 643 break; 644 default: 645 break; 646 } 647 648 try_send(); 649 } 650 651 static void show_usage(void){ 652 printf("\n--- LE Audio Broadcast Source Test Console ---\n"); 653 print_config(); 654 printf("---\n"); 655 printf("c - toggle channels\n"); 656 printf("f - next sampling frequency\n"); 657 printf("v - next codec variant\n"); 658 printf("t - toggle sine / modplayer\n"); 659 printf("s - start broadcast\n"); 660 printf("x - shutdown\n"); 661 printf("---\n"); 662 } 663 664 static void stdin_process(char c){ 665 switch (c){ 666 case 'c': 667 if (app_state != APP_IDLE){ 668 printf("Codec configuration can only be changed in idle state\n"); 669 break; 670 } 671 num_bis = 3 - num_bis; 672 print_config(); 673 break; 674 case 'f': 675 if (app_state != APP_IDLE){ 676 printf("Codec configuration can only be changed in idle state\n"); 677 break; 678 } 679 menu_sampling_frequency++; 680 if (menu_sampling_frequency >= 6){ 681 menu_sampling_frequency = 0; 682 } 683 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 684 menu_variant = 0; 685 } 686 print_config(); 687 break; 688 case 'v': 689 if (app_state != APP_IDLE){ 690 printf("Codec configuration can only be changed in idle state\n"); 691 break; 692 } 693 menu_variant++; 694 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 695 menu_variant = 0; 696 } 697 print_config(); 698 break; 699 case 'x': 700 #ifdef COUNT_MODE 701 printf("Send statistic:\n"); 702 { 703 uint16_t i; 704 for (i=0;i<MAX_PACKET_INTERVAL_BINS_MS;i++){ 705 printf("%2u: %5u\n", i, send_time_bins[i]); 706 } 707 } 708 #endif 709 printf("Shutdown...\n"); 710 hci_power_control(HCI_POWER_OFF); 711 break; 712 case 's': 713 if (app_state != APP_IDLE){ 714 printf("Cannot start broadcast - not in idle state\n"); 715 break; 716 } 717 // use values from table 718 sampling_frequency_hz = codec_configurations[menu_sampling_frequency].samplingrate_hz; 719 octets_per_frame = codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame; 720 frame_duration = codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration; 721 722 // get num samples per frame 723 setup_lc3_encoder(); 724 725 // update BASEs 726 periodic_adv_data_1[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 727 periodic_adv_data_1[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 728 little_endian_store_16(periodic_adv_data_1, 23, octets_per_frame); 729 730 periodic_adv_data_2[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 731 periodic_adv_data_2[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 732 little_endian_store_16(periodic_adv_data_2, 23, octets_per_frame); 733 734 // setup mod player 735 setup_mod_player(); 736 737 // setup sine generator 738 if (sampling_frequency_hz == 44100){ 739 sine_step = 2; 740 } else { 741 sine_step = 96000 / sampling_frequency_hz; 742 } 743 744 // setup 745 app_state = APP_W4_PERIODIC_ENABLED; 746 gap_extended_advertising_setup(&le_advertising_set, &extended_params, &adv_handle); 747 gap_extended_advertising_set_adv_data(adv_handle, sizeof(extended_adv_data), extended_adv_data); 748 gap_periodic_advertising_set_params(adv_handle, &periodic_params); 749 switch(num_bis){ 750 case 1: 751 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_1), periodic_adv_data_1); 752 printf("BASE: "); 753 printf_hexdump(periodic_adv_data_1, sizeof(periodic_adv_data_1)); 754 break; 755 case 2: 756 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_2), periodic_adv_data_2); 757 printf("BASE: "); 758 printf_hexdump(periodic_adv_data_2, sizeof(periodic_adv_data_2)); 759 break; 760 default: 761 btstack_unreachable(); 762 break; 763 } 764 gap_periodic_advertising_start(adv_handle, 0); 765 gap_extended_advertising_start(adv_handle, 0, 0); 766 break; 767 case 't': 768 audio_source = 1 - audio_source; 769 print_config(); 770 break; 771 case '\n': 772 case '\r': 773 break; 774 default: 775 show_usage(); 776 break; 777 } 778 } 779 780 int btstack_main(int argc, const char * argv[]); 781 int btstack_main(int argc, const char * argv[]){ 782 (void) argv; 783 (void) argc; 784 785 // register for HCI events 786 hci_event_callback_registration.callback = &packet_handler; 787 hci_add_event_handler(&hci_event_callback_registration); 788 789 // turn on! 790 hci_power_control(HCI_POWER_ON); 791 792 btstack_stdin_setup(stdin_process); 793 return 0; 794 } 795