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 static void generate_audio_and_encode(void){ 461 uint8_t i; 462 generate_audio(); 463 for (i = 0; i < num_bis; i++) { 464 encode(i); 465 bis_has_data[i] = true; 466 } 467 } 468 469 static void create_big(void){ 470 // Create BIG 471 big_params.big_handle = 0; 472 big_params.advertising_handle = adv_handle; 473 big_params.num_bis = num_bis; 474 big_params.max_sdu = octets_per_frame; 475 big_params.max_transport_latency_ms = 31; 476 big_params.rtn = 2; 477 big_params.phy = 2; 478 big_params.packing = 0; 479 big_params.encryption = 0; 480 memset(big_params.broadcast_code, 0, 16); 481 if (sampling_frequency_hz == 44100){ 482 // same config as for 48k -> frame is longer by 48/44.1 483 big_params.sdu_interval_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 8163 : 10884; 484 big_params.framing = 1; 485 } else { 486 big_params.sdu_interval_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 7500 : 10000; 487 big_params.framing = 0; 488 } 489 app_state = APP_W4_CREATE_BIG_COMPLETE; 490 gap_big_create(&big_storage, &big_params); 491 } 492 493 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 494 UNUSED(channel); 495 if (packet_type != HCI_EVENT_PACKET) return; 496 uint8_t bis_index; 497 498 switch (packet[0]) { 499 case BTSTACK_EVENT_STATE: 500 switch(btstack_event_state_get_state(packet)) { 501 case HCI_STATE_WORKING: 502 show_usage(); 503 printf("Please select sample frequency and variation, then start broadcast\n"); 504 break; 505 case HCI_STATE_OFF: 506 printf("Goodbye\n"); 507 exit(0); 508 break; 509 default: 510 break; 511 } 512 break; 513 case HCI_EVENT_COMMAND_COMPLETE: 514 switch (hci_event_command_complete_get_command_opcode(packet)){ 515 case HCI_OPCODE_HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE: 516 if (app_state != APP_W4_PERIODIC_ENABLED) break; 517 create_big(); 518 break; 519 default: 520 break; 521 } 522 break; 523 case HCI_EVENT_META_GAP: 524 switch (hci_event_gap_meta_get_subevent_code(packet)){ 525 case GAP_SUBEVENT_BIG_CREATED: 526 printf("BIG Created with BIS Connection handles: \n"); 527 for (bis_index=0;bis_index<num_bis;bis_index++){ 528 bis_con_handles[bis_index] = gap_subevent_big_created_get_bis_con_handles(packet, bis_index); 529 printf("0x%04x ", bis_con_handles[bis_index]); 530 } 531 app_state = APP_STREAMING; 532 printf("Start streaming\n"); 533 generate_audio_and_encode(); 534 hci_request_bis_can_send_now_events(big_params.big_handle); 535 break; 536 default: 537 break; 538 } 539 break; 540 case HCI_EVENT_BIS_CAN_SEND_NOW: 541 send_iso_packet(hci_event_bis_can_send_now_get_bis_index(packet)); 542 bis_index++; 543 if (bis_index == num_bis){ 544 generate_audio_and_encode(); 545 hci_request_bis_can_send_now_events(big_params.big_handle); 546 } 547 break; 548 default: 549 break; 550 } 551 } 552 553 static void show_usage(void){ 554 printf("\n--- LE Audio Broadcast Source Test Console ---\n"); 555 print_config(); 556 printf("---\n"); 557 printf("c - toggle channels\n"); 558 printf("f - next sampling frequency\n"); 559 printf("v - next codec variant\n"); 560 printf("t - toggle sine / modplayer\n"); 561 printf("s - start broadcast\n"); 562 printf("x - shutdown\n"); 563 printf("---\n"); 564 } 565 566 static void stdin_process(char c){ 567 switch (c){ 568 case 'c': 569 if (app_state != APP_IDLE){ 570 printf("Codec configuration can only be changed in idle state\n"); 571 break; 572 } 573 num_bis = 3 - num_bis; 574 print_config(); 575 break; 576 case 'f': 577 if (app_state != APP_IDLE){ 578 printf("Codec configuration can only be changed in idle state\n"); 579 break; 580 } 581 menu_sampling_frequency++; 582 if (menu_sampling_frequency >= 6){ 583 menu_sampling_frequency = 0; 584 } 585 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 586 menu_variant = 0; 587 } 588 print_config(); 589 break; 590 case 'v': 591 if (app_state != APP_IDLE){ 592 printf("Codec configuration can only be changed in idle state\n"); 593 break; 594 } 595 menu_variant++; 596 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 597 menu_variant = 0; 598 } 599 print_config(); 600 break; 601 case 'x': 602 #ifdef COUNT_MODE 603 printf("Send statistic:\n"); 604 { 605 uint16_t i; 606 for (i=0;i<MAX_PACKET_INTERVAL_BINS_MS;i++){ 607 printf("%2u: %5u\n", i, send_time_bins[i]); 608 } 609 } 610 #endif 611 printf("Shutdown...\n"); 612 app_state = APP_W4_POWER_OFF; 613 hci_power_control(HCI_POWER_OFF); 614 break; 615 case 's': 616 if (app_state != APP_IDLE){ 617 printf("Cannot start broadcast - not in idle state\n"); 618 break; 619 } 620 // use values from table 621 sampling_frequency_hz = codec_configurations[menu_sampling_frequency].samplingrate_hz; 622 octets_per_frame = codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame; 623 frame_duration = codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration; 624 625 // get num samples per frame 626 setup_lc3_encoder(); 627 628 // update BASEs 629 periodic_adv_data_1[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 630 periodic_adv_data_1[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 631 little_endian_store_16(periodic_adv_data_1, 23, octets_per_frame); 632 633 periodic_adv_data_2[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 634 periodic_adv_data_2[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 635 little_endian_store_16(periodic_adv_data_2, 23, octets_per_frame); 636 637 // setup mod player 638 setup_mod_player(); 639 640 // setup sine generator 641 if (sampling_frequency_hz == 44100){ 642 sine_step = 2; 643 } else { 644 sine_step = 96000 / sampling_frequency_hz; 645 } 646 647 // setup 648 app_state = APP_W4_PERIODIC_ENABLED; 649 gap_extended_advertising_setup(&le_advertising_set, &extended_params, &adv_handle); 650 gap_extended_advertising_set_adv_data(adv_handle, sizeof(extended_adv_data), extended_adv_data); 651 gap_periodic_advertising_set_params(adv_handle, &periodic_params); 652 switch(num_bis){ 653 case 1: 654 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_1), periodic_adv_data_1); 655 printf("BASE: "); 656 printf_hexdump(periodic_adv_data_1, sizeof(periodic_adv_data_1)); 657 break; 658 case 2: 659 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_2), periodic_adv_data_2); 660 printf("BASE: "); 661 printf_hexdump(periodic_adv_data_2, sizeof(periodic_adv_data_2)); 662 break; 663 default: 664 btstack_unreachable(); 665 break; 666 } 667 gap_periodic_advertising_start(adv_handle, 0); 668 gap_extended_advertising_start(adv_handle, 0, 0); 669 break; 670 case 't': 671 audio_source = 1 - audio_source; 672 print_config(); 673 break; 674 case '\n': 675 case '\r': 676 break; 677 default: 678 show_usage(); 679 break; 680 } 681 } 682 683 int btstack_main(int argc, const char * argv[]); 684 int btstack_main(int argc, const char * argv[]){ 685 (void) argv; 686 (void) argc; 687 688 // register for HCI events 689 hci_event_callback_registration.callback = &packet_handler; 690 hci_add_event_handler(&hci_event_callback_registration); 691 692 // turn on! 693 hci_power_control(HCI_POWER_ON); 694 695 btstack_stdin_setup(stdin_process); 696 return 0; 697 } 698