xref: /btstack/test/le_audio/le_audio_broadcast_source.c (revision 4a9eead824c50b40e12b6f72611a74a3f57a47f6)
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 // create audio based on timer instead of num completed packets
70 // #define GENERATE_AUDIO_WITH_TIMER
71 
72 // max config
73 #define MAX_NUM_BIS 2
74 #define MAX_SAMPLES_PER_FRAME 480
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 // time stamping
222 #ifdef COUNT_MODE
223 #define MAX_PACKET_INTERVAL_BINS_MS 50
224 static uint32_t send_time_bins[MAX_PACKET_INTERVAL_BINS_MS];
225 static uint32_t send_last_ms;
226 #endif
227 
228 // time based sender
229 #ifdef GENERATE_AUDIO_WITH_TIMER
230 static uint32_t next_send_time_ms;
231 static uint32_t next_send_time_additional_us;
232 static btstack_timer_source_t send_timer;
233 #endif
234 
235 // lc3 codec config
236 static uint32_t sampling_frequency_hz;
237 static btstack_lc3_frame_duration_t frame_duration;
238 static uint16_t number_samples_per_frame;
239 static uint16_t octets_per_frame;
240 static uint8_t  num_bis = 1;
241 
242 // lc3 encoder
243 static const btstack_lc3_encoder_t * lc3_encoder;
244 static btstack_lc3_encoder_google_t encoder_contexts[MAX_NUM_BIS];
245 static int16_t pcm[MAX_NUM_BIS * MAX_SAMPLES_PER_FRAME];
246 static uint32_t time_generation_ms;
247 
248 // codec menu
249 static uint8_t menu_sampling_frequency;
250 static uint8_t menu_variant;
251 
252 // mod player
253 static int hxcmod_initialized;
254 static modcontext mod_context;
255 static tracker_buffer_state trkbuf;
256 
257 // sine generator
258 static uint8_t  sine_step;
259 static uint16_t sine_phases[MAX_NUM_BIS];
260 
261 // audio producer
262 static enum {
263     AUDIO_SOURCE_SINE,
264     AUDIO_SOURCE_MODPLAYER
265 } audio_source = AUDIO_SOURCE_MODPLAYER;
266 
267 static enum {
268     APP_IDLE,
269     APP_W4_PERIODIC_ENABLED,
270     APP_CREATE_BIG,
271     APP_W4_CREATE_BIG_COMPLETE,
272     APP_SET_ISO_PATH,
273     APP_STREAMING
274 } app_state = APP_IDLE;
275 
276 // enumerate default codec configs
277 static struct {
278     uint32_t samplingrate_hz;
279     uint8_t  samplingrate_index;
280     uint8_t  num_variants;
281     struct {
282         const char * name;
283         btstack_lc3_frame_duration_t frame_duration;
284         uint16_t octets_per_frame;
285     } variants[6];
286 } codec_configurations[] = {
287     {
288         8000, 0x01, 2,
289         {
290             {  "8_1",  BTSTACK_LC3_FRAME_DURATION_7500US, 26},
291             {  "8_2", BTSTACK_LC3_FRAME_DURATION_10000US, 30}
292         }
293     },
294     {
295        16000, 0x03, 2,
296        {
297             {  "16_1",  BTSTACK_LC3_FRAME_DURATION_7500US, 30},
298             {  "16_2", BTSTACK_LC3_FRAME_DURATION_10000US, 40}
299        }
300     },
301     {
302         24000, 0x05, 2,
303         {
304             {  "24_1",  BTSTACK_LC3_FRAME_DURATION_7500US, 45},
305             {  "24_2", BTSTACK_LC3_FRAME_DURATION_10000US, 60}
306        }
307     },
308     {
309         32000, 0x06, 2,
310         {
311             {  "32_1",  BTSTACK_LC3_FRAME_DURATION_7500US, 60},
312             {  "32_2", BTSTACK_LC3_FRAME_DURATION_10000US, 80}
313         }
314     },
315     {
316         44100, 0x07, 2,
317         {
318             { "441_1",  BTSTACK_LC3_FRAME_DURATION_7500US,  97},
319             { "441_2", BTSTACK_LC3_FRAME_DURATION_10000US, 130}
320         }
321     },
322     {
323         48000, 0x08, 6,
324         {
325             {  "48_1", BTSTACK_LC3_FRAME_DURATION_7500US, 75},
326             {  "48_2", BTSTACK_LC3_FRAME_DURATION_10000US, 100},
327             {  "48_3", BTSTACK_LC3_FRAME_DURATION_7500US, 90},
328             {  "48_4", BTSTACK_LC3_FRAME_DURATION_10000US, 120},
329             {  "48_5", BTSTACK_LC3_FRAME_DURATION_7500US, 117},
330             {  "48_6", BTSTACK_LC3_FRAME_DURATION_10000US, 155}
331         }
332     },
333 };
334 
335 static void show_usage(void);
336 
337 static void print_config(void) {
338     printf("Config '%s_%u': %u, %s ms, %u octets - %s\n",
339            codec_configurations[menu_sampling_frequency].variants[menu_variant].name,
340            num_bis,
341            codec_configurations[menu_sampling_frequency].samplingrate_hz,
342            codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10",
343            codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame,
344            audio_source == AUDIO_SOURCE_SINE ? "Sine" : "Modplayer");
345 }
346 
347 static void setup_lc3_encoder(void){
348     uint8_t channel;
349     for (channel = 0 ; channel < num_bis ; channel++){
350         btstack_lc3_encoder_google_t * context = &encoder_contexts[channel];
351         lc3_encoder = btstack_lc3_encoder_google_init_instance(context);
352         lc3_encoder->configure(context, sampling_frequency_hz, frame_duration);
353     }
354     number_samples_per_frame = lc3_encoder->get_number_samples_per_frame(&encoder_contexts[0]);
355     btstack_assert(number_samples_per_frame <= MAX_SAMPLES_PER_FRAME);
356     printf("LC3 Encoder config: %u hz, frame duration %s ms, num samples %u, num octets %u\n",
357            sampling_frequency_hz, frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? "7.5" : "10",
358            number_samples_per_frame, octets_per_frame);
359 }
360 
361 static void setup_mod_player(void){
362     if (!hxcmod_initialized) {
363         hxcmod_initialized = hxcmod_init(&mod_context);
364         btstack_assert(hxcmod_initialized != 0);
365     }
366     hxcmod_unload(&mod_context);
367     hxcmod_setcfg(&mod_context, sampling_frequency_hz, 16, 1, 1, 1);
368     hxcmod_load(&mod_context, (void *) &mod_data, mod_len);
369 }
370 
371 static void generate_audio(void){
372     uint32_t start_ms = btstack_run_loop_get_time_ms();
373     uint16_t sample;
374     switch (audio_source) {
375         case AUDIO_SOURCE_SINE:
376             // generate sine wave for all channels
377             for (sample = 0 ; sample < number_samples_per_frame ; sample++){
378                 uint8_t channel;
379                 for (channel = 0; channel < num_bis; channel++) {
380                     int16_t value = sine_int16[sine_phases[channel]] / 4;
381                     pcm[sample * num_bis + channel] = value;
382                     sine_phases[channel] += sine_step * (1+channel);    // second channel, double frequency
383                     if (sine_phases[channel] >= (sizeof(sine_int16) / sizeof(int16_t))) {
384                         sine_phases[channel] = 0;
385                     }
386                 }
387             }
388             break;
389         case AUDIO_SOURCE_MODPLAYER:
390             // mod player configured for stereo
391             hxcmod_fillbuffer(&mod_context, (unsigned short *) pcm, number_samples_per_frame, &trkbuf);
392             if (num_bis == 1) {
393                 // stereo -> mono
394                 uint16_t i;
395                 for (i=0;i<number_samples_per_frame;i++){
396                     pcm[i] = (pcm[2*i] / 2) + (pcm[2*i+1] / 2);
397                 }
398             }
399             break;
400         default:
401             btstack_unreachable();
402             break;
403     }
404     time_generation_ms = btstack_run_loop_get_time_ms() - start_ms;
405     iso_frame_counter++;
406 }
407 
408 static void encode_and_send(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     // encode as lc3
442     lc3_encoder->encode_signed_16(&encoder_contexts[bis_index], &pcm[bis_index], num_bis, &buffer[8], octets_per_frame);
443 #endif
444     // send
445     hci_send_iso_packet_buffer(4 + 0 + 4 + octets_per_frame);
446 
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 
455     packet_sequence_numbers[bis_index]++;
456 }
457 
458 static void try_send(void){
459     bool all_can_send = true;
460     uint8_t i;
461     for (i=0; i<num_bis;i++) {
462         all_can_send &= bis_can_send[i];
463     }
464 #ifdef PTS_MODE
465    static uint8_t next_sender;
466     // PTS 8.2 sends a packet after the previous one was received -> it sends at half speed for stereo configuration
467     if (all_can_send) {
468         if (next_sender == 0) {
469             generate_audio();
470         }
471         bis_can_send[next_sender] = false;
472         encode_and_send(next_sender);
473         next_sender = (num_bis - 1) - next_sender;
474     }
475 #else
476 #ifdef GENERATE_AUDIO_WITH_TIMER
477     for (i=0;i<num_bis;i++){
478         if (hci_is_packet_buffer_reserved()) return;
479         if (bis_has_data[i]){
480             bis_can_send[i] = false;
481             bis_has_data[i] = false;
482             encode_and_send(i);
483             return;
484         }
485     }
486 #else
487     // check if next audio frame should be produced and send
488     if (all_can_send){
489         generate_audio();
490         for (i=0; i<num_bis;i++) {
491             bis_has_data[i] = true;
492         }
493     }
494 
495     for (i=0;i<num_bis;i++){
496         if (hci_is_packet_buffer_reserved()) return;
497         if (bis_can_send[i] && bis_has_data[i]){
498             bis_can_send[i] = false;
499             bis_has_data[i] = false;
500             encode_and_send(i);
501             return;
502         }
503     }
504 #endif
505 #endif
506 }
507 
508 #ifdef GENERATE_AUDIO_WITH_TIMER
509 static void generate_audio_timer_handler(btstack_timer_source_t *ts){
510 
511     generate_audio();
512 
513     uint8_t i;
514     for (i=0; i<num_bis;i++) {
515         bis_has_data[i] = true;
516     }
517 
518     // next send time based on frame_duration_us
519     next_send_time_additional_us += frame_duration_us % 1000;
520     if (next_send_time_additional_us > 1000){
521         next_send_time_ms++;
522         next_send_time_additional_us -= 1000;
523     }
524     next_send_time_ms += frame_duration_us / 1000;
525 
526     uint32_t now = btstack_run_loop_get_time_ms();
527     btstack_run_loop_set_timer(&send_timer, next_send_time_ms - now);
528     btstack_run_loop_add_timer(&send_timer);
529 
530     try_send();
531 }
532 #endif
533 
534 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
535     UNUSED(channel);
536     if (packet_type != HCI_EVENT_PACKET) return;
537 
538     switch (packet[0]) {
539         case BTSTACK_EVENT_STATE:
540             switch(btstack_event_state_get_state(packet)) {
541                 case HCI_STATE_WORKING:
542                     show_usage();
543                     printf("Please select sample frequency and variation, then start broadcast\n");
544                     break;
545                 case HCI_STATE_OFF:
546                     printf("Goodbye\n");
547                     exit(0);
548                     break;
549                 default:
550                     break;
551             }
552             break;
553         case HCI_EVENT_COMMAND_COMPLETE:
554             switch (hci_event_command_complete_get_command_opcode(packet)){
555                 case HCI_OPCODE_HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE:
556                     if (app_state != APP_W4_PERIODIC_ENABLED) break;
557                     app_state = APP_CREATE_BIG;
558                     break;
559                 case HCI_OPCODE_HCI_LE_SETUP_ISO_DATA_PATH:
560                     next_bis_index++;
561                     if (next_bis_index == num_bis){
562                         printf("%u ISO path(s) set up\n", num_bis);
563                         // ready to send
564                         uint8_t i;
565                         for (i=0;i<num_bis;i++) {
566                             bis_can_send[i] = true;
567                         }
568                         app_state = APP_STREAMING;
569                         //
570 #ifdef GENERATE_AUDIO_WITH_TIMER
571                         btstack_run_loop_set_timer_handler(&send_timer, &generate_audio_timer_handler);
572                         uint32_t next_send_time_ms = btstack_run_loop_get_time_ms() + 10;
573                         uint32_t now = btstack_run_loop_get_time_ms();
574                         btstack_run_loop_set_timer(&send_timer, next_send_time_ms - now);
575                         btstack_run_loop_add_timer(&send_timer);
576 #endif
577                     }
578                     break;
579             }
580             break;
581         case HCI_EVENT_LE_META:
582             switch(hci_event_le_meta_get_subevent_code(packet)){
583                 case HCI_SUBEVENT_LE_CREATE_BIG_COMPLETE:
584                     if (app_state == APP_W4_CREATE_BIG_COMPLETE){
585                         uint8_t i;
586                         printf("BIS Connection Handles: ");
587                         for (i=0;i<num_bis;i++){
588                             bis_con_handles[i] = little_endian_read_16(packet, 21 + 2*i);
589                             printf("0x%04x ", bis_con_handles[i]);
590                         }
591                         printf("\n");
592                         next_bis_index = 0;
593                         app_state = APP_SET_ISO_PATH;
594                         printf("Start streaming\n");
595                     }
596                     break;
597                 default:
598                     break;
599             }
600             break;
601         case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS:
602             if (size >= 3){
603                 uint16_t num_handles = packet[2];
604                 if (size != (3u + num_handles * 4u)) break;
605                 uint16_t offset = 3;
606                 uint16_t i;
607                 for (i=0; i<num_handles;i++) {
608                     hci_con_handle_t handle = little_endian_read_16(packet, offset) & 0x0fffu;
609                     offset += 2u;
610                     uint16_t num_packets = little_endian_read_16(packet, offset);
611                     offset += 2u;
612                     uint8_t j;
613                     for (j=0 ; j<num_bis ; j++){
614                         if (handle == bis_con_handles[j]){
615                             // allow to send
616                             bis_can_send[j] = true;
617                         }
618                     }
619                 }
620             }
621             break;
622         default:
623             break;
624     }
625 
626     const uint8_t broadcast_code[16] = { 0 };
627     switch(app_state){
628         case APP_CREATE_BIG:
629             if (hci_can_send_command_packet_now()) {
630                 app_state = APP_W4_CREATE_BIG_COMPLETE;
631                 if (sampling_frequency_hz == 44100){
632                     framed_pdus = 1;
633                     // same config as for 48k -> frame is longer by 48/44.1
634                     frame_duration_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 8163 : 10884;
635                 } else {
636                     framed_pdus = 0;
637                     frame_duration_us = frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US ? 7500 : 10000;
638                 }
639                 hci_send_cmd(&hci_le_create_big, 0, adv_handle, num_bis, frame_duration_us, octets_per_frame, 0x1F, 2, 2, 0, framed_pdus, 0, broadcast_code);
640             }
641             break;
642         case APP_SET_ISO_PATH:
643             if (!hci_can_send_command_packet_now()) break;
644             hci_send_cmd(&hci_le_setup_iso_data_path, bis_con_handles[next_bis_index], 0, 0,  0, 0, 0,  0, 0, NULL);
645             break;
646         default:
647             break;
648     }
649 
650     try_send();
651 }
652 
653 static void show_usage(void){
654     printf("\n--- LE Audio Broadcast Source Test Console ---\n");
655     print_config();
656     printf("---\n");
657     printf("c - toggle channels\n");
658     printf("f - next sampling frequency\n");
659     printf("v - next codec variant\n");
660     printf("t - toggle sine / modplayer\n");
661     printf("s - start broadcast\n");
662     printf("x - shutdown\n");
663     printf("---\n");
664 }
665 
666 static void stdin_process(char c){
667     switch (c){
668         case 'c':
669             if (app_state != APP_IDLE){
670                 printf("Codec configuration can only be changed in idle state\n");
671                 break;
672             }
673             num_bis = 3 - num_bis;
674             print_config();
675             break;
676         case 'f':
677             if (app_state != APP_IDLE){
678                 printf("Codec configuration can only be changed in idle state\n");
679                 break;
680             }
681             menu_sampling_frequency++;
682             if (menu_sampling_frequency >= 6){
683                 menu_sampling_frequency = 0;
684             }
685             if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){
686                 menu_variant = 0;
687             }
688             print_config();
689             break;
690         case 'v':
691             if (app_state != APP_IDLE){
692                 printf("Codec configuration can only be changed in idle state\n");
693                 break;
694             }
695             menu_variant++;
696             if (menu_variant >= codec_configurations[menu_sampling_frequency].num_variants){
697                 menu_variant = 0;
698             }
699             print_config();
700             break;
701         case 'x':
702 #ifdef COUNT_MODE
703             printf("Send statistic:\n");
704             {
705                 uint16_t i;
706                 for (i=0;i<MAX_PACKET_INTERVAL_BINS_MS;i++){
707                     printf("%2u: %5u\n", i, send_time_bins[i]);
708                 }
709             }
710 #endif
711             printf("Shutdown...\n");
712             hci_power_control(HCI_POWER_OFF);
713             break;
714         case 's':
715             if (app_state != APP_IDLE){
716                 printf("Cannot start broadcast - not in idle state\n");
717                 break;
718             }
719             // use values from table
720             sampling_frequency_hz = codec_configurations[menu_sampling_frequency].samplingrate_hz;
721             octets_per_frame      = codec_configurations[menu_sampling_frequency].variants[menu_variant].octets_per_frame;
722             frame_duration        = codec_configurations[menu_sampling_frequency].variants[menu_variant].frame_duration;
723 
724             // get num samples per frame
725             setup_lc3_encoder();
726 
727             // update BASEs
728             periodic_adv_data_1[17] = codec_configurations[menu_sampling_frequency].samplingrate_index;
729             periodic_adv_data_1[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1;
730             little_endian_store_16(periodic_adv_data_1, 23, octets_per_frame);
731 
732             periodic_adv_data_2[17] = codec_configurations[menu_sampling_frequency].samplingrate_index;
733             periodic_adv_data_2[20] = (frame_duration == BTSTACK_LC3_FRAME_DURATION_7500US) ? 0 : 1;
734             little_endian_store_16(periodic_adv_data_2, 23, octets_per_frame);
735 
736             // setup mod player
737             setup_mod_player();
738 
739             // setup sine generator
740             if (sampling_frequency_hz == 44100){
741                 sine_step = 2;
742             } else {
743                 sine_step = 96000 / sampling_frequency_hz;
744             }
745 
746             // setup
747             app_state = APP_W4_PERIODIC_ENABLED;
748             gap_extended_advertising_setup(&le_advertising_set, &extended_params, &adv_handle);
749             gap_extended_advertising_set_adv_data(adv_handle, sizeof(extended_adv_data), extended_adv_data);
750             gap_periodic_advertising_set_params(adv_handle, &periodic_params);
751             switch(num_bis){
752                 case 1:
753                     gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_1), periodic_adv_data_1);
754                     printf("BASE: ");
755                     printf_hexdump(periodic_adv_data_1, sizeof(periodic_adv_data_1));
756                     break;
757                 case 2:
758                     gap_periodic_advertising_set_data(adv_handle, sizeof(periodic_adv_data_2), periodic_adv_data_2);
759                     printf("BASE: ");
760                     printf_hexdump(periodic_adv_data_2, sizeof(periodic_adv_data_2));
761                     break;
762                 default:
763                     btstack_unreachable();
764                     break;
765             }
766             gap_periodic_advertising_start(adv_handle, 0);
767             gap_extended_advertising_start(adv_handle, 0, 0);
768             break;
769         case 't':
770             audio_source = 1 - audio_source;
771             print_config();
772             break;
773         case '\n':
774         case '\r':
775             break;
776         default:
777             show_usage();
778             break;
779     }
780 }
781 
782 int btstack_main(int argc, const char * argv[]);
783 int btstack_main(int argc, const char * argv[]){
784     (void) argv;
785     (void) argc;
786 
787     // register for HCI events
788     hci_event_callback_registration.callback = &packet_handler;
789     hci_add_event_handler(&hci_event_callback_registration);
790 
791     // turn on!
792     hci_power_control(HCI_POWER_ON);
793 
794     btstack_stdin_setup(stdin_process);
795     return 0;
796 }
797