xref: /btstack/test/le_audio/le_audio_broadcast_source.c (revision 6162bc33ff76292b3737386bf647a8de3396db6c)
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