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