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 73 static const uint8_t adv_sid = 0; 74 75 static le_advertising_set_t le_advertising_set; 76 77 static const le_extended_advertising_parameters_t extended_params = { 78 .advertising_event_properties = 0, 79 .primary_advertising_interval_min = 0x4b0, // 750 ms 80 .primary_advertising_interval_max = 0x4b0, // 750 ms 81 .primary_advertising_channel_map = 7, 82 .own_address_type = 0, 83 .peer_address_type = 0, 84 .peer_address = 0, 85 .advertising_filter_policy = 0, 86 .advertising_tx_power = 10, // 10 dBm 87 .primary_advertising_phy = 1, // LE 1M PHY 88 .secondary_advertising_max_skip = 0, 89 .secondary_advertising_phy = 1, // LE 1M PHY 90 .advertising_sid = adv_sid, 91 .scan_request_notification_enable = 0, 92 }; 93 94 static const uint8_t extended_adv_data[] = { 95 // 16 bit service data, ORG_BLUETOOTH_SERVICE_BASIC_AUDIO_ANNOUNCEMENT_SERVICE, Broadcast ID 96 6, BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID, 0x52, 0x18, 0x30, 0x5d, 0x9b, 97 // name 98 #ifdef PTS_MODE 99 7, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'P', 'T', 'S', '-', 'x', 'x' 100 #elif defined(COUNT_MODE) 101 6, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'C', 'O', 'U', 'N', 'T' 102 #else 103 7, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'S', 'o', 'u', 'r', 'c', 'e' 104 #endif 105 }; 106 107 static const le_periodic_advertising_parameters_t periodic_params = { 108 .periodic_advertising_interval_min = 0x258, // 375 ms 109 .periodic_advertising_interval_max = 0x258, // 375 ms 110 .periodic_advertising_properties = 0 111 }; 112 113 static uint8_t periodic_adv_data_1[] = { 114 // 16 bit service data 115 37, BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID, 116 // Level 1 - BIG Parameters (common to all BISes) 117 0x51, 0x18, // Basic Audio Announcement Service UUID 118 0x28, 0x00, 0x00, // Presentation Delay 3 119 0x01, // Num_Subgroups 120 // Level 2 - BIS Subgroup Parameters (common parameters for subgroups of BISes) 121 // offset 8 122 0x01, // The number of BISes in this subgroup 123 0x06, 0x00, 0x00, 0x00, 0x00, // 0x06 = LC3, vendor id + codec id = 0 124 10, // Codec_Specific_Configuration_Length[i] 125 // Codec_Specific_Configuration[i] = 8_2 126 // offset 15 127 0x02, 0x01, 0x01, // Sampling frequency 0x01 = 0x01 / 8 kHz 128 0x02, 0x02, 0x01, // Frame Duration 0x02 = 0x01 / 10 ms 129 0x03, 0x04, 0x1E, 0x00, // Octets per Frame 0x04 = 0x1e / 30 130 4, // Metadata_Length[i] 131 0x03, 0x02, 0x04, 0x00, // Metadata[i] 132 // Level 3 - Specific BIS Parameters (if required, for individual BISes) 133 0x01, // BIS_index[i[k]] 134 6, // Codec_Specific_Configuration_Length[i[k]] 135 0x05, 0x03, 0x01, 0x00, 0x00, 0x00 // Codec_Specific_Configuration[i[k]] 136 }; 137 138 static uint8_t periodic_adv_data_2[] = { 139 // 16 bit service data 140 37+8, BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID, 141 // Level 1 - BIG Parameters (common to all BISes) 142 0x51, 0x18, // Basic Audio Announcement Service UUID 143 0x28, 0x00, 0x00, // Presentation Delay 3 144 0x01, // Num_Subgroups 145 // Level 2 - BIS Subgroup Parameters (common parameters for subgroups of BISes) 146 // offset 8 147 0x02, // The number of BISes in this subgroup 148 0x06, 0x00, 0x00, 0x00, 0x00, // 0x06 = LC3, vendor id + codec id = 0 149 10, // Codec_Specific_Configuration_Length[i] 150 // Codec_Specific_Configuration[0] = 8_2 151 // offset 15 152 0x02, 0x01, 0x01, // Sampling frequency 0x01 = 0x01 / 8 kHz 153 0x02, 0x02, 0x01, // Frame Duration 0x02 = 0x01 / 10 ms 154 0x03, 0x04, 0x1E, 0x00, // Octets per Frame 0x04 = 0x1e / 30 155 4, // Metadata_Length[i] 156 0x03, 0x02, 0x04, 0x00, // Metadata[0] 157 // Level 3 - Specific BIS Parameters (if required, for individual BISes) 158 0x01, // BIS_index[i[k]] 159 6, // Codec_Specific_Configuration_Length[i[k]] 160 0x05, 0x03, 0x01, 0x00, 0x00, 0x00, // Codec_Specific_Configuration[i[k]] 161 // Level 3 - Specific BIS Parameters (if required, for individual BISes) 162 0x02, // BIS_index[i[k]] 163 6, // Codec_Specific_Configuration_Length[i[k]] 164 0x05, 0x03, 0x02, 0x00, 0x00, 0x00 // Codec_Specific_Configuration[i[k]] 165 }; 166 167 // input signal: pre-computed int16 sine wave, 96000 Hz at 300 Hz 168 static const int16_t sine_int16[] = { 169 0, 643, 1286, 1929, 2571, 3212, 3851, 4489, 5126, 5760, 170 6393, 7022, 7649, 8273, 8894, 9512, 10126, 10735, 11341, 11943, 171 12539, 13131, 13718, 14300, 14876, 15446, 16011, 16569, 17121, 17666, 172 18204, 18736, 19260, 19777, 20286, 20787, 21280, 21766, 22242, 22710, 173 23170, 23620, 24062, 24494, 24916, 25329, 25732, 26126, 26509, 26882, 174 27245, 27597, 27938, 28269, 28589, 28898, 29196, 29482, 29757, 30021, 175 30273, 30513, 30742, 30958, 31163, 31356, 31537, 31705, 31862, 32006, 176 32137, 32257, 32364, 32458, 32540, 32609, 32666, 32710, 32742, 32761, 177 32767, 32761, 32742, 32710, 32666, 32609, 32540, 32458, 32364, 32257, 178 32137, 32006, 31862, 31705, 31537, 31356, 31163, 30958, 30742, 30513, 179 30273, 30021, 29757, 29482, 29196, 28898, 28589, 28269, 27938, 27597, 180 27245, 26882, 26509, 26126, 25732, 25329, 24916, 24494, 24062, 23620, 181 23170, 22710, 22242, 21766, 21280, 20787, 20286, 19777, 19260, 18736, 182 18204, 17666, 17121, 16569, 16011, 15446, 14876, 14300, 13718, 13131, 183 12539, 11943, 11341, 10735, 10126, 9512, 8894, 8273, 7649, 7022, 184 6393, 5760, 5126, 4489, 3851, 3212, 2571, 1929, 1286, 643, 185 0, -643, -1286, -1929, -2571, -3212, -3851, -4489, -5126, -5760, 186 -6393, -7022, -7649, -8273, -8894, -9512, -10126, -10735, -11341, -11943, 187 -12539, -13131, -13718, -14300, -14876, -15446, -16011, -16569, -17121, -17666, 188 -18204, -18736, -19260, -19777, -20286, -20787, -21280, -21766, -22242, -22710, 189 -23170, -23620, -24062, -24494, -24916, -25329, -25732, -26126, -26509, -26882, 190 -27245, -27597, -27938, -28269, -28589, -28898, -29196, -29482, -29757, -30021, 191 -30273, -30513, -30742, -30958, -31163, -31356, -31537, -31705, -31862, -32006, 192 -32137, -32257, -32364, -32458, -32540, -32609, -32666, -32710, -32742, -32761, 193 -32767, -32761, -32742, -32710, -32666, -32609, -32540, -32458, -32364, -32257, 194 -32137, -32006, -31862, -31705, -31537, -31356, -31163, -30958, -30742, -30513, 195 -30273, -30021, -29757, -29482, -29196, -28898, -28589, -28269, -27938, -27597, 196 -27245, -26882, -26509, -26126, -25732, -25329, -24916, -24494, -24062, -23620, 197 -23170, -22710, -22242, -21766, -21280, -20787, -20286, -19777, -19260, -18736, 198 -18204, -17666, -17121, -16569, -16011, -15446, -14876, -14300, -13718, -13131, 199 -12539, -11943, -11341, -10735, -10126, -9512, -8894, -8273, -7649, -7022, 200 -6393, -5760, -5126, -4489, -3851, -3212, -2571, -1929, -1286, -643, 201 }; 202 203 static bd_addr_t remote; 204 static const char * remote_addr_string = "00:1B:DC:08:E2:72"; 205 206 static btstack_packet_callback_registration_t hci_event_callback_registration; 207 208 static uint8_t adv_handle = 0; 209 static unsigned int next_bis_index; 210 static hci_con_handle_t bis_con_handles[MAX_NUM_BIS]; 211 static uint16_t packet_sequence_numbers[MAX_NUM_BIS]; 212 static uint8_t framed_pdus; 213 static bool bis_can_send[MAX_NUM_BIS]; 214 static bool bis_has_data[MAX_NUM_BIS]; 215 static uint8_t iso_frame_counter; 216 static uint16_t frame_duration_us; 217 218 static le_audio_big_t big_storage; 219 static le_audio_big_params_t big_params; 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 // lc3 codec config 229 static uint32_t sampling_frequency_hz; 230 static btstack_lc3_frame_duration_t frame_duration; 231 static uint16_t number_samples_per_frame; 232 static uint16_t octets_per_frame; 233 static uint8_t num_bis = 1; 234 235 // lc3 encoder 236 static const btstack_lc3_encoder_t * lc3_encoder; 237 static btstack_lc3_encoder_google_t encoder_contexts[MAX_NUM_BIS]; 238 static int16_t pcm[MAX_NUM_BIS * MAX_SAMPLES_PER_FRAME]; 239 static uint32_t time_generation_ms; 240 241 // codec menu 242 static uint8_t menu_sampling_frequency; 243 static uint8_t menu_variant; 244 245 // mod player 246 static int hxcmod_initialized; 247 static modcontext mod_context; 248 static tracker_buffer_state trkbuf; 249 250 // sine generator 251 static uint8_t sine_step; 252 static uint16_t sine_phases[MAX_NUM_BIS]; 253 254 // audio producer 255 static enum { 256 AUDIO_SOURCE_SINE, 257 AUDIO_SOURCE_MODPLAYER 258 } audio_source = AUDIO_SOURCE_MODPLAYER; 259 260 static enum { 261 APP_IDLE, 262 APP_W4_PERIODIC_ENABLED, 263 APP_W4_CREATE_BIG_COMPLETE, 264 APP_STREAMING, 265 APP_W4_POWER_OFF, 266 } app_state = APP_IDLE; 267 268 // enumerate default codec configs 269 static struct { 270 uint32_t samplingrate_hz; 271 uint8_t samplingrate_index; 272 uint8_t num_variants; 273 struct { 274 const char * name; 275 btstack_lc3_frame_duration_t frame_duration; 276 uint16_t octets_per_frame; 277 } variants[6]; 278 } codec_configurations[] = { 279 { 280 8000, 0x01, 2, 281 { 282 { "8_1", BTSTACK_LC3_FRAME_DURATION_7500US, 26}, 283 { "8_2", BTSTACK_LC3_FRAME_DURATION_10000US, 30} 284 } 285 }, 286 { 287 16000, 0x03, 2, 288 { 289 { "16_1", BTSTACK_LC3_FRAME_DURATION_7500US, 30}, 290 { "16_2", BTSTACK_LC3_FRAME_DURATION_10000US, 40} 291 } 292 }, 293 { 294 24000, 0x05, 2, 295 { 296 { "24_1", BTSTACK_LC3_FRAME_DURATION_7500US, 45}, 297 { "24_2", BTSTACK_LC3_FRAME_DURATION_10000US, 60} 298 } 299 }, 300 { 301 32000, 0x06, 2, 302 { 303 { "32_1", BTSTACK_LC3_FRAME_DURATION_7500US, 60}, 304 { "32_2", BTSTACK_LC3_FRAME_DURATION_10000US, 80} 305 } 306 }, 307 { 308 44100, 0x07, 2, 309 { 310 { "441_1", BTSTACK_LC3_FRAME_DURATION_7500US, 97}, 311 { "441_2", BTSTACK_LC3_FRAME_DURATION_10000US, 130} 312 } 313 }, 314 { 315 48000, 0x08, 6, 316 { 317 { "48_1", BTSTACK_LC3_FRAME_DURATION_7500US, 75}, 318 { "48_2", BTSTACK_LC3_FRAME_DURATION_10000US, 100}, 319 { "48_3", BTSTACK_LC3_FRAME_DURATION_7500US, 90}, 320 { "48_4", BTSTACK_LC3_FRAME_DURATION_10000US, 120}, 321 { "48_5", BTSTACK_LC3_FRAME_DURATION_7500US, 117}, 322 { "48_6", BTSTACK_LC3_FRAME_DURATION_10000US, 155} 323 } 324 }, 325 }; 326 327 static void show_usage(void); 328 329 static void print_config(void) { 330 printf("Config '%s_%u': %u, %s ms, %u octets - %s\n", 331 codec_configurations[menu_sampling_frequency].variants[menu_variant].name, 332 num_bis, 333 codec_configurations[menu_sampling_frequency].samplingrate_hz, 334 codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10", 335 codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame, 336 audio_source == AUDIO_SOURCE_SINE ? "Sine" : "Modplayer"); 337 } 338 339 static void setup_lc3_encoder(void){ 340 uint8_t channel; 341 for (channel = 0 ; channel < num_bis ; channel++){ 342 btstack_lc3_encoder_google_t * context = &encoder_contexts[channel]; 343 lc3_encoder = btstack_lc3_encoder_google_init_instance(context); 344 lc3_encoder->configure(context, sampling_frequency_hz, frame_duration); 345 } 346 number_samples_per_frame = lc3_encoder->get_number_samples_per_frame(&encoder_contexts[0]); 347 btstack_assert(number_samples_per_frame <= MAX_SAMPLES_PER_FRAME); 348 printf("LC3 Encoder config: %u hz, frame duration %s ms, num samples %u, num octets %u\n", 349 sampling_frequency_hz, frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10", 350 number_samples_per_frame, octets_per_frame); 351 } 352 353 static void setup_mod_player(void){ 354 if (!hxcmod_initialized) { 355 hxcmod_initialized = hxcmod_init(&mod_context); 356 btstack_assert(hxcmod_initialized != 0); 357 } 358 hxcmod_unload(&mod_context); 359 hxcmod_setcfg(&mod_context, sampling_frequency_hz, 16, 1, 1, 1); 360 hxcmod_load(&mod_context, (void *) &mod_data, mod_len); 361 } 362 363 static void generate_audio(void){ 364 uint32_t start_ms = btstack_run_loop_get_time_ms(); 365 uint16_t sample; 366 switch (audio_source) { 367 case AUDIO_SOURCE_SINE: 368 // generate sine wave for all channels 369 for (sample = 0 ; sample < number_samples_per_frame ; sample++){ 370 uint8_t channel; 371 for (channel = 0; channel < num_bis; channel++) { 372 int16_t value = sine_int16[sine_phases[channel]] / 4; 373 pcm[sample * num_bis + channel] = value; 374 sine_phases[channel] += sine_step * (1+channel); // second channel, double frequency 375 if (sine_phases[channel] >= (sizeof(sine_int16) / sizeof(int16_t))) { 376 sine_phases[channel] = 0; 377 } 378 } 379 } 380 break; 381 case AUDIO_SOURCE_MODPLAYER: 382 // mod player configured for stereo 383 hxcmod_fillbuffer(&mod_context, (unsigned short *) pcm, number_samples_per_frame, &trkbuf); 384 if (num_bis == 1) { 385 // stereo -> mono 386 uint16_t i; 387 for (i=0;i<number_samples_per_frame;i++){ 388 pcm[i] = (pcm[2*i] / 2) + (pcm[2*i+1] / 2); 389 } 390 } 391 break; 392 default: 393 btstack_unreachable(); 394 break; 395 } 396 time_generation_ms = btstack_run_loop_get_time_ms() - start_ms; 397 iso_frame_counter++; 398 } 399 400 static void encode_and_send(uint8_t bis_index){ 401 402 #ifdef COUNT_MODE 403 if (bis_index == 0) { 404 uint32_t now = btstack_run_loop_get_time_ms(); 405 if (send_last_ms != 0) { 406 uint16_t send_interval_ms = now - send_last_ms; 407 if (send_interval_ms >= MAX_PACKET_INTERVAL_BINS_MS) { 408 printf("ERROR: send interval %u\n", send_interval_ms); 409 } else { 410 send_time_bins[send_interval_ms]++; 411 } 412 } 413 send_last_ms = now; 414 } 415 #endif 416 bool ok = hci_reserve_packet_buffer(); 417 btstack_assert(ok); 418 uint8_t * buffer = hci_get_outgoing_packet_buffer(); 419 // complete SDU, no TimeStamp 420 little_endian_store_16(buffer, 0, bis_con_handles[bis_index] | (2 << 12)); 421 // len 422 little_endian_store_16(buffer, 2, 0 + 4 + octets_per_frame); 423 // TimeStamp if TS flag is set 424 // packet seq nr 425 little_endian_store_16(buffer, 4, packet_sequence_numbers[bis_index]); 426 // iso sdu len 427 little_endian_store_16(buffer, 6, octets_per_frame); 428 #ifdef COUNT_MODE 429 // test data: bis_index, counter 430 buffer[8] = bis_index; 431 memset(&buffer[9], iso_frame_counter, octets_per_frame - 1); 432 #else 433 // encode as lc3 434 lc3_encoder->encode_signed_16(&encoder_contexts[bis_index], &pcm[bis_index], num_bis, &buffer[8], octets_per_frame); 435 #endif 436 // send 437 hci_send_iso_packet_buffer(4 + 0 + 4 + octets_per_frame); 438 439 if (((packet_sequence_numbers[bis_index] & 0x7f) == 0) && (bis_index == 0)) { 440 printf("Encoding time: %u\n", time_generation_ms); 441 } 442 if ((packet_sequence_numbers[bis_index] & 0x7c) == 0){ 443 printf("%04x %10u %u ", packet_sequence_numbers[bis_index], btstack_run_loop_get_time_ms(), bis_index); 444 printf_hexdump(&buffer[8], octets_per_frame); 445 } 446 447 packet_sequence_numbers[bis_index]++; 448 } 449 450 static void try_send(void){ 451 if (app_state != APP_STREAMING) return; 452 453 bool all_can_send = true; 454 uint8_t i; 455 for (i=0; i<num_bis;i++) { 456 all_can_send &= bis_can_send[i]; 457 } 458 #ifdef PTS_MODE 459 static uint8_t next_sender; 460 // PTS 8.2 sends a packet after the previous one was received -> it sends at half speed for stereo configuration 461 if (all_can_send) { 462 if (next_sender == 0) { 463 generate_audio(); 464 } 465 bis_can_send[next_sender] = false; 466 encode_and_send(next_sender); 467 next_sender = (num_bis - 1) - next_sender; 468 } 469 #else 470 // check if next audio frame should be produced and send 471 if (all_can_send){ 472 generate_audio(); 473 for (i=0; i<num_bis;i++) { 474 bis_has_data[i] = true; 475 } 476 } 477 478 for (i=0;i<num_bis;i++){ 479 if (hci_is_packet_buffer_reserved()) return; 480 if (bis_can_send[i] && bis_has_data[i]){ 481 bis_can_send[i] = false; 482 bis_has_data[i] = false; 483 encode_and_send(i); 484 return; 485 } 486 } 487 #endif 488 } 489 490 static void create_big(void){ 491 // Create BIG 492 big_params.big_handle = 0; 493 big_params.advertising_handle = adv_handle; 494 big_params.num_bis = num_bis; 495 big_params.max_sdu = octets_per_frame; 496 big_params.max_transport_latency_ms = 31; 497 big_params.rtn = 2; 498 big_params.phy = 2; 499 big_params.packing = 0; 500 big_params.encryption = 0; 501 memset(big_params.broadcast_code, 0, 16); 502 if (sampling_frequency_hz == 44100){ 503 // same config as for 48k -> frame is longer by 48/44.1 504 big_params.sdu_interval_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 8163 : 10884; 505 big_params.framing = 1; 506 } else { 507 big_params.sdu_interval_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 7500 : 10000; 508 big_params.framing = 0; 509 } 510 app_state = APP_W4_CREATE_BIG_COMPLETE; 511 gap_big_create(&big_storage, &big_params); 512 } 513 514 static void ready_to_send(void){ 515 // ready to send 516 uint8_t i; 517 for (i=0;i<num_bis;i++) { 518 bis_can_send[i] = true; 519 } 520 app_state = APP_STREAMING; 521 } 522 523 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 524 UNUSED(channel); 525 if (packet_type != HCI_EVENT_PACKET) return; 526 527 switch (packet[0]) { 528 case BTSTACK_EVENT_STATE: 529 switch(btstack_event_state_get_state(packet)) { 530 case HCI_STATE_WORKING: 531 show_usage(); 532 printf("Please select sample frequency and variation, then start broadcast\n"); 533 break; 534 case HCI_STATE_OFF: 535 printf("Goodbye\n"); 536 exit(0); 537 break; 538 default: 539 break; 540 } 541 break; 542 case HCI_EVENT_COMMAND_COMPLETE: 543 switch (hci_event_command_complete_get_command_opcode(packet)){ 544 case HCI_OPCODE_HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE: 545 if (app_state != APP_W4_PERIODIC_ENABLED) break; 546 create_big(); 547 break; 548 default: 549 break; 550 } 551 break; 552 case HCI_EVENT_META_GAP: 553 switch (hci_event_gap_meta_get_subevent_code(packet)){ 554 case GAP_SUBEVENT_BIG_CREATED: { 555 printf("BIG Created with BIS Connection handles: \n"); 556 uint8_t i; 557 for (i=0;i<num_bis;i++){ 558 bis_con_handles[i] = gap_subevent_big_created_get_bis_con_handles(packet, i); 559 printf("0x%04x ", bis_con_handles[i]); 560 } 561 ready_to_send(); 562 app_state = APP_STREAMING; 563 printf("Start streaming\n"); 564 break; 565 } 566 default: 567 break; 568 } 569 break; 570 case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS: 571 if (size >= 3){ 572 uint16_t num_handles = packet[2]; 573 if (size != (3u + num_handles * 4u)) break; 574 uint16_t offset = 3; 575 uint16_t i; 576 for (i=0; i<num_handles;i++) { 577 hci_con_handle_t handle = little_endian_read_16(packet, offset) & 0x0fffu; 578 offset += 2u; 579 uint16_t num_packets = little_endian_read_16(packet, offset); 580 offset += 2u; 581 uint8_t j; 582 for (j=0 ; j<num_bis ; j++){ 583 if (handle == bis_con_handles[j]){ 584 // allow to send 585 bis_can_send[j] = true; 586 } 587 } 588 } 589 } 590 break; 591 default: 592 break; 593 } 594 595 try_send(); 596 } 597 598 static void show_usage(void){ 599 printf("\n--- LE Audio Broadcast Source Test Console ---\n"); 600 print_config(); 601 printf("---\n"); 602 printf("c - toggle channels\n"); 603 printf("f - next sampling frequency\n"); 604 printf("v - next codec variant\n"); 605 printf("t - toggle sine / modplayer\n"); 606 printf("s - start broadcast\n"); 607 printf("x - shutdown\n"); 608 printf("---\n"); 609 } 610 611 static void stdin_process(char c){ 612 switch (c){ 613 case 'c': 614 if (app_state != APP_IDLE){ 615 printf("Codec configuration can only be changed in idle state\n"); 616 break; 617 } 618 num_bis = 3 - num_bis; 619 print_config(); 620 break; 621 case 'f': 622 if (app_state != APP_IDLE){ 623 printf("Codec configuration can only be changed in idle state\n"); 624 break; 625 } 626 menu_sampling_frequency++; 627 if (menu_sampling_frequency >= 6){ 628 menu_sampling_frequency = 0; 629 } 630 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 631 menu_variant = 0; 632 } 633 print_config(); 634 break; 635 case 'v': 636 if (app_state != APP_IDLE){ 637 printf("Codec configuration can only be changed in idle state\n"); 638 break; 639 } 640 menu_variant++; 641 if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){ 642 menu_variant = 0; 643 } 644 print_config(); 645 break; 646 case 'x': 647 #ifdef COUNT_MODE 648 printf("Send statistic:\n"); 649 { 650 uint16_t i; 651 for (i=0;i<MAX_PACKET_INTERVAL_BINS_MS;i++){ 652 printf("%2u: %5u\n", i, send_time_bins[i]); 653 } 654 } 655 #endif 656 printf("Shutdown...\n"); 657 app_state = APP_W4_POWER_OFF; 658 hci_power_control(HCI_POWER_OFF); 659 break; 660 case 's': 661 if (app_state != APP_IDLE){ 662 printf("Cannot start broadcast - not in idle state\n"); 663 break; 664 } 665 // use values from table 666 sampling_frequency_hz = codec_configurations[menu_sampling_frequency].samplingrate_hz; 667 octets_per_frame = codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame; 668 frame_duration = codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration; 669 670 // get num samples per frame 671 setup_lc3_encoder(); 672 673 // update BASEs 674 periodic_adv_data_1[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 675 periodic_adv_data_1[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 676 little_endian_store_16(periodic_adv_data_1, 23, octets_per_frame); 677 678 periodic_adv_data_2[17] = codec_configurations[menu_sampling_frequency].samplingrate_index; 679 periodic_adv_data_2[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1; 680 little_endian_store_16(periodic_adv_data_2, 23, octets_per_frame); 681 682 // setup mod player 683 setup_mod_player(); 684 685 // setup sine generator 686 if (sampling_frequency_hz == 44100){ 687 sine_step = 2; 688 } else { 689 sine_step = 96000 / sampling_frequency_hz; 690 } 691 692 // setup 693 app_state = APP_W4_PERIODIC_ENABLED; 694 gap_extended_advertising_setup(&le_advertising_set, &extended_params, &adv_handle); 695 gap_extended_advertising_set_adv_data(adv_handle, sizeof(extended_adv_data), extended_adv_data); 696 gap_periodic_advertising_set_params(adv_handle, &periodic_params); 697 switch(num_bis){ 698 case 1: 699 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_1), periodic_adv_data_1); 700 printf("BASE: "); 701 printf_hexdump(periodic_adv_data_1, sizeof(periodic_adv_data_1)); 702 break; 703 case 2: 704 gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_2), periodic_adv_data_2); 705 printf("BASE: "); 706 printf_hexdump(periodic_adv_data_2, sizeof(periodic_adv_data_2)); 707 break; 708 default: 709 btstack_unreachable(); 710 break; 711 } 712 gap_periodic_advertising_start(adv_handle, 0); 713 gap_extended_advertising_start(adv_handle, 0, 0); 714 break; 715 case 't': 716 audio_source = 1 - audio_source; 717 print_config(); 718 break; 719 case '\n': 720 case '\r': 721 break; 722 default: 723 show_usage(); 724 break; 725 } 726 } 727 728 int btstack_main(int argc, const char * argv[]); 729 int btstack_main(int argc, const char * argv[]){ 730 (void) argv; 731 (void) argc; 732 733 // register for HCI events 734 hci_event_callback_registration.callback = &packet_handler; 735 hci_add_event_handler(&hci_event_callback_registration); 736 737 // turn on! 738 hci_power_control(HCI_POWER_ON); 739 740 btstack_stdin_setup(stdin_process); 741 return 0; 742 } 743