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