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 #define ENABLE_DEMO_MODE 45 46 #include <stdint.h> 47 #include <stdio.h> 48 #include <string.h> 49 #include <btstack_debug.h> 50 51 #include "bluetooth_data_types.h" 52 #include "btstack_stdin.h" 53 #include "btstack_event.h" 54 #include "btstack_run_loop.h" 55 #include "gap.h" 56 #include "hci.h" 57 #include "hci_cmd.h" 58 #include "hci_dump.h" 59 #include "btstack_lc3.h" 60 #include "btstack_lc3_google.h" 61 62 #include "hxcmod.h" 63 #include "mods/mod.h" 64 65 // PTS mode 66 // #define PTS_MODE 67 68 // Count mode - send packet count as test data for manual analysis 69 // #define COUNT_MODE 70 71 // max config 72 #define MAX_NUM_BIS 2 73 #define MAX_SAMPLES_PER_FRAME 480 74 #define MAX_LC3_FRAME_BYTES 155 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 // lc3 codec config 232 static uint16_t sampling_frequency_hz; 233 static btstack_lc3_frame_duration_t frame_duration; 234 static uint16_t number_samples_per_frame; 235 static uint16_t octets_per_frame; 236 static uint8_t num_bis = 1; 237 238 // lc3 encoder 239 static const btstack_lc3_encoder_t * lc3_encoder; 240 static btstack_lc3_encoder_google_t encoder_contexts[MAX_NUM_BIS]; 241 static int16_t pcm[MAX_NUM_BIS * MAX_SAMPLES_PER_FRAME]; 242 static uint8_t iso_payload[MAX_NUM_BIS * MAX_LC3_FRAME_BYTES]; 243 static uint32_t time_generation_ms; 244 245 // codec menu 246 static uint8_t menu_sampling_frequency; 247 static uint8_t menu_variant; 248 249 // mod player 250 static int hxcmod_initialized; 251 static modcontext mod_context; 252 static tracker_buffer_state trkbuf; 253 254 // sine generator 255 static uint8_t sine_step; 256 static uint16_t sine_phases[MAX_NUM_BIS]; 257 258 // audio producer 259 static enum { 260 AUDIO_SOURCE_SINE, 261 AUDIO_SOURCE_MODPLAYER 262 } audio_source = AUDIO_SOURCE_MODPLAYER; 263 264 static enum { 265 APP_IDLE, 266 APP_W4_CREATE_BIG_COMPLETE, 267 APP_STREAMING, 268 APP_W4_POWER_OFF, 269 } app_state = APP_IDLE; 270 271 // enumerate default codec configs 272 static struct { 273 uint16_t samplingrate_hz; 274 uint8_t samplingrate_index; 275 uint8_t num_variants; 276 struct { 277 const char * name; 278 btstack_lc3_frame_duration_t frame_duration; 279 uint16_t octets_per_frame; 280 } variants[6]; 281 } codec_configurations[] = { 282 { 283 8000, 0x01, 2, 284 { 285 { "8_1", BTSTACK_LC3_FRAME_DURATION_7500US, 26}, 286 { "8_2", BTSTACK_LC3_FRAME_DURATION_10000US, 30} 287 } 288 }, 289 { 290 16000, 0x03, 2, 291 { 292 { "16_1", BTSTACK_LC3_FRAME_DURATION_7500US, 30}, 293 { "16_2", BTSTACK_LC3_FRAME_DURATION_10000US, 40} 294 } 295 }, 296 { 297 24000, 0x05, 2, 298 { 299 { "24_1", BTSTACK_LC3_FRAME_DURATION_7500US, 45}, 300 { "24_2", BTSTACK_LC3_FRAME_DURATION_10000US, 60} 301 } 302 }, 303 { 304 32000, 0x06, 2, 305 { 306 { "32_1", BTSTACK_LC3_FRAME_DURATION_7500US, 60}, 307 { "32_2", BTSTACK_LC3_FRAME_DURATION_10000US, 80} 308 } 309 }, 310 { 311 44100, 0x07, 2, 312 { 313 { "441_1", BTSTACK_LC3_FRAME_DURATION_7500US, 97}, 314 { "441_2", BTSTACK_LC3_FRAME_DURATION_10000US, 130} 315 } 316 }, 317 { 318 48000, 0x08, 6, 319 { 320 { "48_1", BTSTACK_LC3_FRAME_DURATION_7500US, 75}, 321 { "48_2", BTSTACK_LC3_FRAME_DURATION_10000US, 100}, 322 { "48_3", BTSTACK_LC3_FRAME_DURATION_7500US, 90}, 323 { "48_4", BTSTACK_LC3_FRAME_DURATION_10000US, 120}, 324 { "48_5", BTSTACK_LC3_FRAME_DURATION_7500US, 117}, 325 { "48_6", BTSTACK_LC3_FRAME_DURATION_10000US, 155} 326 } 327 }, 328 }; 329 330 static void show_usage(void); 331 332 static void print_config(void) { 333 printf("Config '%s_%u': %u, %s ms, %u octets - %s\n", 334 codec_configurations[menu_sampling_frequency].variants[menu_variant].name, 335 num_bis, 336 codec_configurations[menu_sampling_frequency].samplingrate_hz, 337 codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10", 338 codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame, 339 audio_source == AUDIO_SOURCE_SINE ? "Sine" : "Modplayer"); 340 } 341 342 static void setup_lc3_encoder(void){ 343 uint8_t channel; 344 for (channel = 0 ; channel < num_bis ; channel++){ 345 btstack_lc3_encoder_google_t * context = &encoder_contexts[channel]; 346 lc3_encoder = btstack_lc3_encoder_google_init_instance(context); 347 lc3_encoder->configure(context, sampling_frequency_hz, frame_duration); 348 } 349 number_samples_per_frame = lc3_encoder->get_number_samples_per_frame(&encoder_contexts[0]); 350 btstack_assert(number_samples_per_frame <= MAX_SAMPLES_PER_FRAME); 351 printf("LC3 Encoder config: %u hz, frame duration %s ms, num samples %u, num octets %u\n", 352 sampling_frequency_hz, frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10", 353 number_samples_per_frame, octets_per_frame); 354 } 355 356 static void setup_mod_player(void){ 357 if (!hxcmod_initialized) { 358 hxcmod_initialized = hxcmod_init(&mod_context); 359 btstack_assert(hxcmod_initialized != 0); 360 } 361 hxcmod_unload(&mod_context); 362 hxcmod_setcfg(&mod_context, sampling_frequency_hz, 16, 1, 1, 1); 363 hxcmod_load(&mod_context, (void *) &mod_data, mod_len); 364 } 365 366 static void generate_audio(void){ 367 uint32_t start_ms = btstack_run_loop_get_time_ms(); 368 uint16_t sample; 369 switch (audio_source) { 370 case AUDIO_SOURCE_SINE: 371 // generate sine wave for all channels 372 for (sample = 0 ; sample < number_samples_per_frame ; sample++){ 373 uint8_t channel; 374 for (channel = 0; channel < num_bis; channel++) { 375 int16_t value = sine_int16[sine_phases[channel]] / 4; 376 pcm[sample * num_bis + channel] = value; 377 sine_phases[channel] += sine_step * (1+channel); // second channel, double frequency 378 if (sine_phases[channel] >= (sizeof(sine_int16) / sizeof(int16_t))) { 379 sine_phases[channel] = 0; 380 } 381 } 382 } 383 break; 384 case AUDIO_SOURCE_MODPLAYER: 385 // mod player configured for stereo 386 hxcmod_fillbuffer(&mod_context, (unsigned short *) pcm, number_samples_per_frame, &trkbuf); 387 if (num_bis == 1) { 388 // stereo -> mono 389 uint16_t i; 390 for (i=0;i<number_samples_per_frame;i++){ 391 pcm[i] = (pcm[2*i] / 2) + (pcm[2*i+1] / 2); 392 } 393 } 394 break; 395 default: 396 btstack_unreachable(); 397 break; 398 } 399 time_generation_ms = btstack_run_loop_get_time_ms() - start_ms; 400 iso_frame_counter++; 401 } 402 403 static void encode(uint8_t bis_index){ 404 // encode as lc3 405 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); 406 } 407 408 409 static void send_iso_packet(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 // copy encoded payload 443 memcpy(&buffer[8], &iso_payload[bis_index * MAX_LC3_FRAME_BYTES], octets_per_frame); 444 #endif 445 // send 446 hci_send_iso_packet_buffer(4 + 0 + 4 + octets_per_frame); 447 448 #ifdef HAVE_POSIX_FILE_IO 449 if (((packet_sequence_numbers[bis_index] & 0x7f) == 0) && (bis_index == 0)) { 450 printf("Encoding time: %u\n", time_generation_ms); 451 } 452 if ((packet_sequence_numbers[bis_index] & 0x7c) == 0){ 453 printf("%04x %10u %u ", packet_sequence_numbers[bis_index], btstack_run_loop_get_time_ms(), bis_index); 454 printf_hexdump(&buffer[8], octets_per_frame); 455 } 456 #endif 457 458 packet_sequence_numbers[bis_index]++; 459 } 460 461 static void generate_audio_and_encode(void){ 462 uint8_t i; 463 generate_audio(); 464 for (i = 0; i < num_bis; i++) { 465 encode(i); 466 bis_has_data[i] = true; 467 } 468 } 469 470 static void setup_advertising() { 471 gap_extended_advertising_setup(&le_advertising_set, &extended_params, &adv_handle); 472 gap_extended_advertising_set_adv_data(adv_handle, sizeof(extended_adv_data), extended_adv_data); 473 gap_periodic_advertising_set_params(adv_handle, &periodic_params); 474 switch(num_bis){ 475 case 1: 476 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_1), periodic_adv_data_1); 477 printf("BASE: "); 478 printf_hexdump(periodic_adv_data_1, sizeof(periodic_adv_data_1)); 479 break; 480 case 2: 481 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_2), periodic_adv_data_2); 482 printf("BASE: "); 483 printf_hexdump(periodic_adv_data_2, sizeof(periodic_adv_data_2)); 484 break; 485 default: 486 btstack_unreachable(); 487 break; 488 } 489 gap_periodic_advertising_start(adv_handle, 0); 490 gap_extended_advertising_start(adv_handle, 0, 0); 491 } 492 493 static void setup_big(void){ 494 // Create BIG 495 big_params.big_handle = 0; 496 big_params.advertising_handle = adv_handle; 497 big_params.num_bis = num_bis; 498 big_params.max_sdu = octets_per_frame; 499 big_params.max_transport_latency_ms = 31; 500 big_params.rtn = 2; 501 big_params.phy = 2; 502 big_params.packing = 0; 503 big_params.encryption = 0; 504 memset(big_params.broadcast_code, 0, 16); 505 if (sampling_frequency_hz == 44100){ 506 // same config as for 48k -> frame is longer by 48/44.1 507 big_params.sdu_interval_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 8163 : 10884; 508 big_params.framing = 1; 509 } else { 510 big_params.sdu_interval_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 7500 : 10000; 511 big_params.framing = 0; 512 } 513 app_state = APP_W4_CREATE_BIG_COMPLETE; 514 gap_big_create(&big_storage, &big_params); 515 } 516 517 518 static void start_broadcast() {// use values from table 519 sampling_frequency_hz = codec_configurations[menu_sampling_frequency].samplingrate_hz; 520 octets_per_frame = codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame; 521 frame_duration = codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration; 522 523 // get num samples per frame 524 setup_lc3_encoder(); 525 526 // update BASEs 527 periodic_adv_data_1[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 528 periodic_adv_data_1[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 529 little_endian_store_16(periodic_adv_data_1, 23, octets_per_frame); 530 531 periodic_adv_data_2[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 532 periodic_adv_data_2[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 533 little_endian_store_16(periodic_adv_data_2, 23, octets_per_frame); 534 535 // setup mod player 536 setup_mod_player(); 537 538 // setup sine generator 539 if (sampling_frequency_hz == 44100){ 540 sine_step = 2; 541 } else { 542 sine_step = 96000 / sampling_frequency_hz; 543 } 544 545 // setup extended and periodic advertising 546 setup_advertising(); 547 548 // setup big 549 setup_big(); 550 } 551 552 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 553 UNUSED(channel); 554 if (packet_type != HCI_EVENT_PACKET) return; 555 uint8_t bis_index; 556 557 switch (packet[0]) { 558 case BTSTACK_EVENT_STATE: 559 switch(btstack_event_state_get_state(packet)) { 560 case HCI_STATE_WORKING: 561 #ifdef ENABLE_DEMO_MODE 562 // start broadcast automatically, mod player, 48_5_1 563 num_bis = 1; 564 menu_sampling_frequency = 5; 565 menu_variant = 4; 566 start_broadcast(); 567 #else 568 show_usage(); 569 printf("Please select sample frequency and variation, then start broadcast\n"); 570 #endif 571 break; 572 case HCI_STATE_OFF: 573 printf("Goodbye\n"); 574 exit(0); 575 break; 576 default: 577 break; 578 } 579 break; 580 case HCI_EVENT_META_GAP: 581 switch (hci_event_gap_meta_get_subevent_code(packet)){ 582 case GAP_SUBEVENT_BIG_CREATED: 583 printf("BIG Created with BIS Connection handles: \n"); 584 for (bis_index=0;bis_index<num_bis;bis_index++){ 585 bis_con_handles[bis_index] = gap_subevent_big_created_get_bis_con_handles(packet, bis_index); 586 printf("0x%04x ", bis_con_handles[bis_index]); 587 } 588 589 app_state = APP_STREAMING; 590 printf("Start streaming\n"); 591 generate_audio_and_encode(); 592 hci_request_bis_can_send_now_events(big_params.big_handle); 593 break; 594 default: 595 break; 596 } 597 break; 598 case HCI_EVENT_BIS_CAN_SEND_NOW: 599 send_iso_packet(hci_event_bis_can_send_now_get_bis_index(packet)); 600 bis_index++; 601 if (bis_index == num_bis){ 602 generate_audio_and_encode(); 603 hci_request_bis_can_send_now_events(big_params.big_handle); 604 } 605 break; 606 default: 607 break; 608 } 609 } 610 611 static void show_usage(void){ 612 printf("\n--- LE Audio Broadcast Source Test Console ---\n"); 613 print_config(); 614 printf("---\n"); 615 printf("c - toggle channels\n"); 616 printf("f - next sampling frequency\n"); 617 printf("v - next codec variant\n"); 618 printf("t - toggle sine / modplayer\n"); 619 printf("s - start broadcast\n"); 620 printf("x - shutdown\n"); 621 printf("---\n"); 622 } 623 static void stdin_process(char c){ 624 switch (c){ 625 case 'c': 626 if (app_state != APP_IDLE){ 627 printf("Codec configuration can only be changed in idle state\n"); 628 break; 629 } 630 num_bis = 3 - num_bis; 631 print_config(); 632 break; 633 case 'f': 634 if (app_state != APP_IDLE){ 635 printf("Codec configuration can only be changed in idle state\n"); 636 break; 637 } 638 menu_sampling_frequency++; 639 if (menu_sampling_frequency >= 6){ 640 menu_sampling_frequency = 0; 641 } 642 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 643 menu_variant = 0; 644 } 645 print_config(); 646 break; 647 case 'v': 648 if (app_state != APP_IDLE){ 649 printf("Codec configuration can only be changed in idle state\n"); 650 break; 651 } 652 menu_variant++; 653 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 654 menu_variant = 0; 655 } 656 print_config(); 657 break; 658 case 'x': 659 #ifdef COUNT_MODE 660 printf("Send statistic:\n"); 661 { 662 uint16_t i; 663 for (i=0;i<MAX_PACKET_INTERVAL_BINS_MS;i++){ 664 printf("%2u: %5u\n", i, send_time_bins[i]); 665 } 666 } 667 #endif 668 printf("Shutdown...\n"); 669 app_state = APP_W4_POWER_OFF; 670 hci_power_control(HCI_POWER_OFF); 671 break; 672 case 's': 673 if (app_state != APP_IDLE){ 674 printf("Cannot start broadcast - not in idle state\n"); 675 break; 676 } 677 start_broadcast(); 678 break; 679 case 't': 680 audio_source = 1 - audio_source; 681 print_config(); 682 break; 683 case '\n': 684 case '\r': 685 break; 686 default: 687 show_usage(); 688 break; 689 } 690 } 691 692 int btstack_main(int argc, const char * argv[]); 693 int btstack_main(int argc, const char * argv[]){ 694 (void) argv; 695 (void) argc; 696 697 // register for HCI events 698 hci_event_callback_registration.callback = &packet_handler; 699 hci_add_event_handler(&hci_event_callback_registration); 700 701 // turn on! 702 hci_power_control(HCI_POWER_ON); 703 704 btstack_stdin_setup(stdin_process); 705 return 0; 706 } 707