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