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