xref: /btstack/test/le_audio/le_audio_broadcast_source.c (revision da8e14c5aa3783b6bb7dd63e71572a901bcf168b)
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 uint16_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     uint16_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 
516 static void start_broadcast() {// use values from table
517     sampling_frequency_hz = codec_configurations[menu_sampling_frequency].samplingrate_hz;
518     octets_per_frame      = codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame;
519     frame_duration        = codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration;
520 
521     // get num samples per frame
522     setup_lc3_encoder();
523 
524     // update BASEs
525     periodic_adv_data_1[17] = codec_configurations[menu_sampling_frequency].samplingrate_index;
526     periodic_adv_data_1[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1;
527     little_endian_store_16(periodic_adv_data_1, 23, octets_per_frame);
528 
529     periodic_adv_data_2[17] = codec_configurations[menu_sampling_frequency].samplingrate_index;
530     periodic_adv_data_2[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1;
531     little_endian_store_16(periodic_adv_data_2, 23, octets_per_frame);
532 
533     // setup mod player
534     setup_mod_player();
535 
536     // setup sine generator
537     if (sampling_frequency_hz == 44100){
538         sine_step = 2;
539     } else {
540         sine_step = 96000 / sampling_frequency_hz;
541     }
542 
543     // setup extended and periodic advertising
544     setup_advertising();
545 
546     // setup big
547     setup_big();
548 }
549 
550 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
551     UNUSED(channel);
552     if (packet_type != HCI_EVENT_PACKET) return;
553     uint8_t bis_index;
554 
555     switch (packet[0]) {
556         case BTSTACK_EVENT_STATE:
557             switch(btstack_event_state_get_state(packet)) {
558                 case HCI_STATE_WORKING:
559 #ifdef ENABLE_DEMO_MODE
560                     // start broadcast automatically, mod player, 48_5_1
561                     num_bis = 1;
562                     menu_sampling_frequency = 5;
563                     menu_variant = 4;
564                     start_broadcast();
565 #else
566                     show_usage();
567                     printf("Please select sample frequency and variation, then start broadcast\n");
568 #endif
569                     break;
570                 case HCI_STATE_OFF:
571                     printf("Goodbye\n");
572                     exit(0);
573                     break;
574                 default:
575                     break;
576             }
577             break;
578         case HCI_EVENT_META_GAP:
579             switch (hci_event_gap_meta_get_subevent_code(packet)){
580                 case GAP_SUBEVENT_BIG_CREATED:
581                     printf("BIG Created with BIS Connection handles: \n");
582                     for (bis_index=0;bis_index<num_bis;bis_index++){
583                         bis_con_handles[bis_index] = gap_subevent_big_created_get_bis_con_handles(packet, bis_index);
584                         printf("0x%04x ", bis_con_handles[bis_index]);
585                     }
586 
587                     app_state = APP_STREAMING;
588                     printf("Start streaming\n");
589                     generate_audio_and_encode();
590                     hci_request_bis_can_send_now_events(big_params.big_handle);
591                     break;
592                 default:
593                     break;
594             }
595             break;
596         case HCI_EVENT_BIS_CAN_SEND_NOW:
597             bis_index = hci_event_bis_can_send_now_get_bis_index(packet);
598             send_iso_packet(bis_index);
599             bis_index++;
600             if (bis_index == num_bis){
601                 generate_audio_and_encode();
602                 hci_request_bis_can_send_now_events(big_params.big_handle);
603             }
604             break;
605         default:
606             break;
607     }
608 }
609 
610 static void show_usage(void){
611     printf("\n--- LE Audio Broadcast Source Test Console ---\n");
612     print_config();
613     printf("---\n");
614     printf("c - toggle channels\n");
615     printf("f - next sampling frequency\n");
616     printf("v - next codec variant\n");
617     printf("t - toggle sine / modplayer\n");
618     printf("s - start broadcast\n");
619     printf("x - shutdown\n");
620     printf("---\n");
621 }
622 static void stdin_process(char c){
623     switch (c){
624         case 'c':
625             if (app_state != APP_IDLE){
626                 printf("Codec configuration can only be changed in idle state\n");
627                 break;
628             }
629             num_bis = 3 - num_bis;
630             print_config();
631             break;
632         case 'f':
633             if (app_state != APP_IDLE){
634                 printf("Codec configuration can only be changed in idle state\n");
635                 break;
636             }
637             menu_sampling_frequency++;
638             if (menu_sampling_frequency >= 6){
639                 menu_sampling_frequency = 0;
640             }
641             if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){
642                 menu_variant = 0;
643             }
644             print_config();
645             break;
646         case 'v':
647             if (app_state != APP_IDLE){
648                 printf("Codec configuration can only be changed in idle state\n");
649                 break;
650             }
651             menu_variant++;
652             if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){
653                 menu_variant = 0;
654             }
655             print_config();
656             break;
657         case 'x':
658 #ifdef COUNT_MODE
659             printf("Send statistic:\n");
660             {
661                 uint16_t i;
662                 for (i=0;i<MAX_PACKET_INTERVAL_BINS_MS;i++){
663                     printf("%2u: %5u\n", i, send_time_bins[i]);
664                 }
665             }
666 #endif
667             printf("Shutdown...\n");
668             app_state = APP_W4_POWER_OFF;
669             hci_power_control(HCI_POWER_OFF);
670             break;
671         case 's':
672             if (app_state != APP_IDLE){
673                 printf("Cannot start broadcast - not in idle state\n");
674                 break;
675             }
676             start_broadcast();
677             break;
678         case 't':
679             audio_source = 1 - audio_source;
680             print_config();
681             break;
682         case '\n':
683         case '\r':
684             break;
685         default:
686             show_usage();
687             break;
688     }
689 }
690 
691 int btstack_main(int argc, const char * argv[]);
692 int btstack_main(int argc, const char * argv[]){
693     (void) argv;
694     (void) argc;
695 
696     // register for HCI events
697     hci_event_callback_registration.callback = &packet_handler;
698     hci_add_event_handler(&hci_event_callback_registration);
699 
700     // turn on!
701     hci_power_control(HCI_POWER_ON);
702 
703     btstack_stdin_setup(stdin_process);
704     return 0;
705 }
706