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