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