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