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