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