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 uint32_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 uint32_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 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 518 UNUSED(channel); 519 if (packet_type != HCI_EVENT_PACKET) return; 520 uint8_t bis_index; 521 522 switch (packet[0]) { 523 case BTSTACK_EVENT_STATE: 524 switch(btstack_event_state_get_state(packet)) { 525 case HCI_STATE_WORKING: 526 show_usage(); 527 printf("Please select sample frequency and variation, then start broadcast\n"); 528 break; 529 case HCI_STATE_OFF: 530 printf("Goodbye\n"); 531 exit(0); 532 break; 533 default: 534 break; 535 } 536 break; 537 case HCI_EVENT_META_GAP: 538 switch (hci_event_gap_meta_get_subevent_code(packet)){ 539 case GAP_SUBEVENT_BIG_CREATED: 540 printf("BIG Created with BIS Connection handles: \n"); 541 for (bis_index=0;bis_index<num_bis;bis_index++){ 542 bis_con_handles[bis_index] = gap_subevent_big_created_get_bis_con_handles(packet, bis_index); 543 printf("0x%04x ", bis_con_handles[bis_index]); 544 } 545 546 app_state = APP_STREAMING; 547 printf("Start streaming\n"); 548 generate_audio_and_encode(); 549 hci_request_bis_can_send_now_events(big_params.big_handle); 550 break; 551 default: 552 break; 553 } 554 break; 555 case HCI_EVENT_BIS_CAN_SEND_NOW: 556 send_iso_packet(hci_event_bis_can_send_now_get_bis_index(packet)); 557 bis_index++; 558 if (bis_index == num_bis){ 559 generate_audio_and_encode(); 560 hci_request_bis_can_send_now_events(big_params.big_handle); 561 } 562 break; 563 default: 564 break; 565 } 566 } 567 568 static void show_usage(void){ 569 printf("\n--- LE Audio Broadcast Source Test Console ---\n"); 570 print_config(); 571 printf("---\n"); 572 printf("c - toggle channels\n"); 573 printf("f - next sampling frequency\n"); 574 printf("v - next codec variant\n"); 575 printf("t - toggle sine / modplayer\n"); 576 printf("s - start broadcast\n"); 577 printf("x - shutdown\n"); 578 printf("---\n"); 579 } 580 581 static void stdin_process(char c){ 582 switch (c){ 583 case 'c': 584 if (app_state != APP_IDLE){ 585 printf("Codec configuration can only be changed in idle state\n"); 586 break; 587 } 588 num_bis = 3 - num_bis; 589 print_config(); 590 break; 591 case 'f': 592 if (app_state != APP_IDLE){ 593 printf("Codec configuration can only be changed in idle state\n"); 594 break; 595 } 596 menu_sampling_frequency++; 597 if (menu_sampling_frequency >= 6){ 598 menu_sampling_frequency = 0; 599 } 600 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 601 menu_variant = 0; 602 } 603 print_config(); 604 break; 605 case 'v': 606 if (app_state != APP_IDLE){ 607 printf("Codec configuration can only be changed in idle state\n"); 608 break; 609 } 610 menu_variant++; 611 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 612 menu_variant = 0; 613 } 614 print_config(); 615 break; 616 case 'x': 617 #ifdef COUNT_MODE 618 printf("Send statistic:\n"); 619 { 620 uint16_t i; 621 for (i=0;i<MAX_PACKET_INTERVAL_BINS_MS;i++){ 622 printf("%2u: %5u\n", i, send_time_bins[i]); 623 } 624 } 625 #endif 626 printf("Shutdown...\n"); 627 app_state = APP_W4_POWER_OFF; 628 hci_power_control(HCI_POWER_OFF); 629 break; 630 case 's': 631 if (app_state != APP_IDLE){ 632 printf("Cannot start broadcast - not in idle state\n"); 633 break; 634 } 635 // use values from table 636 sampling_frequency_hz = codec_configurations[menu_sampling_frequency].samplingrate_hz; 637 octets_per_frame = codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame; 638 frame_duration = codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration; 639 640 // get num samples per frame 641 setup_lc3_encoder(); 642 643 // update BASEs 644 periodic_adv_data_1[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 645 periodic_adv_data_1[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 646 little_endian_store_16(periodic_adv_data_1, 23, octets_per_frame); 647 648 periodic_adv_data_2[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 649 periodic_adv_data_2[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 650 little_endian_store_16(periodic_adv_data_2, 23, octets_per_frame); 651 652 // setup mod player 653 setup_mod_player(); 654 655 // setup sine generator 656 if (sampling_frequency_hz == 44100){ 657 sine_step = 2; 658 } else { 659 sine_step = 96000 / sampling_frequency_hz; 660 } 661 662 // setup extended and periodic advertising 663 setup_advertising(); 664 665 // setup big 666 setup_big(); 667 break; 668 case 't': 669 audio_source = 1 - audio_source; 670 print_config(); 671 break; 672 case '\n': 673 case '\r': 674 break; 675 default: 676 show_usage(); 677 break; 678 } 679 } 680 681 int btstack_main(int argc, const char * argv[]); 682 int btstack_main(int argc, const char * argv[]){ 683 (void) argv; 684 (void) argc; 685 686 // register for HCI events 687 hci_event_callback_registration.callback = &packet_handler; 688 hci_add_event_handler(&hci_event_callback_registration); 689 690 // turn on! 691 hci_power_control(HCI_POWER_ON); 692 693 btstack_stdin_setup(stdin_process); 694 return 0; 695 } 696