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