xref: /btstack/example/a2dp_source_demo.c (revision 3c4cc6427fe05577c00b7d2593f58c7abcf9eab7)
1 /*
2  * Copyright (C) 2016 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__ "a2dp_source_demo.c"
39 
40 /*
41  * a2dp_source_demo.c
42  */
43 
44 // *****************************************************************************
45 /* EXAMPLE_START(a2dp_source_demo): Serve audio stream and handle remote playback control and queries.
46  *
47  * @text This  A2DP Source example demonstrates how to send an audio data stream
48  * to a remote A2DP Sink device and how to switch between two audio data sources.
49  * In addition, the AVRCP Target is used to answer queries on currently played media,
50  * as well as to handle remote playback control, i.e. play, stop, repeat, etc.
51  *
52  * @test To test with a remote device, e.g. a Bluetooth speaker,
53  * set the device_addr_string to the Bluetooth address of your
54  * remote device in the code, and use the UI to connect and start playback.
55  * Tap SPACE on the console to show the available commands.
56  */
57 // *****************************************************************************
58 
59 
60 #include <stdint.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 
65 #include "btstack.h"
66 #include "hxcmod.h"
67 #include "mods/mod.h"
68 
69 // logarithmic volume reduction, samples are divided by 2^x
70 // #define VOLUME_REDUCTION 3
71 // #undef  HAVE_BTSTACK_STDIN
72 
73 //#define AVRCP_BROWSING_ENABLED
74 
75 #define NUM_CHANNELS                2
76 #define A2DP_SAMPLE_RATE            44100
77 #define BYTES_PER_AUDIO_SAMPLE      (2*NUM_CHANNELS)
78 #define AUDIO_TIMEOUT_MS            10
79 #define TABLE_SIZE_441HZ            100
80 
81 #define SBC_STORAGE_SIZE 1030
82 
83 typedef enum {
84     STREAM_SINE = 0,
85     STREAM_MOD,
86     STREAM_PTS_TEST
87 } stream_data_source_t;
88 
89 typedef struct {
90     uint16_t a2dp_cid;
91     uint8_t  local_seid;
92     uint8_t  stream_opened;
93     uint16_t avrcp_cid;
94 
95     uint32_t time_audio_data_sent; // ms
96     uint32_t acc_num_missed_samples;
97     uint32_t samples_ready;
98     btstack_timer_source_t audio_timer;
99     uint8_t  streaming;
100     int      max_media_payload_size;
101 
102     uint8_t  sbc_storage[SBC_STORAGE_SIZE];
103     uint16_t sbc_storage_count;
104     uint8_t  sbc_ready_to_send;
105 } a2dp_media_sending_context_t;
106 
107 static  uint8_t media_sbc_codec_capabilities[] = {
108     (AVDTP_SBC_44100 << 4) | AVDTP_SBC_STEREO,
109     0xFF,//(AVDTP_SBC_BLOCK_LENGTH_16 << 4) | (AVDTP_SBC_SUBBANDS_8 << 2) | AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS,
110     2, 53
111 };
112 
113 static const int16_t sine_int16[] = {
114      0,    2057,    4107,    6140,    8149,   10126,   12062,   13952,   15786,   17557,
115  19260,   20886,   22431,   23886,   25247,   26509,   27666,   28714,   29648,   30466,
116  31163,   31738,   32187,   32509,   32702,   32767,   32702,   32509,   32187,   31738,
117  31163,   30466,   29648,   28714,   27666,   26509,   25247,   23886,   22431,   20886,
118  19260,   17557,   15786,   13952,   12062,   10126,    8149,    6140,    4107,    2057,
119      0,   -2057,   -4107,   -6140,   -8149,  -10126,  -12062,  -13952,  -15786,  -17557,
120 -19260,  -20886,  -22431,  -23886,  -25247,  -26509,  -27666,  -28714,  -29648,  -30466,
121 -31163,  -31738,  -32187,  -32509,  -32702,  -32767,  -32702,  -32509,  -32187,  -31738,
122 -31163,  -30466,  -29648,  -28714,  -27666,  -26509,  -25247,  -23886,  -22431,  -20886,
123 -19260,  -17557,  -15786,  -13952,  -12062,  -10126,   -8149,   -6140,   -4107,   -2057,
124 };
125 
126 typedef struct {
127     int reconfigure;
128     int num_channels;
129     int sampling_frequency;
130     int channel_mode;
131     int block_length;
132     int subbands;
133     int allocation_method;
134     int min_bitpool_value;
135     int max_bitpool_value;
136     int frames_per_buffer;
137 } avdtp_media_codec_configuration_sbc_t;
138 
139 static btstack_packet_callback_registration_t hci_event_callback_registration;
140 
141 // pts:             static const char * device_addr_string = "00:1B:DC:08:0A:A5";
142 // pts:             static const char * device_addr_string = "00:1B:DC:08:E2:72";
143 // mac 2013:        static const char * device_addr_string = "84:38:35:65:d1:15";
144 // phone 2013:      static const char * device_addr_string = "D8:BB:2C:DF:F0:F2";
145 // Minijambox:      static const char * device_addr_string = "00:21:3C:AC:F7:38";
146 // Philips SHB9100: static const char * device_addr_string = "00:22:37:05:FD:E8";
147 // RT-B6:           static const char * device_addr_string = "00:75:58:FF:C9:7D";
148 // BT dongle:       static const char * device_addr_string = "00:1A:7D:DA:71:0A";
149 // Sony MDR-ZX330BT
150 static const char * device_addr_string = "00:18:09:28:50:18";
151 // Panda (BM6)      static const char * device_addr_string = "4F:3F:66:52:8B:E0";
152 
153 static bd_addr_t device_addr;
154 static uint8_t sdp_a2dp_source_service_buffer[150];
155 static uint8_t sdp_avrcp_target_service_buffer[200];
156 static uint8_t sdp_avrcp_controller_service_buffer[200];
157 
158 static avdtp_media_codec_configuration_sbc_t sbc_configuration;
159 static btstack_sbc_encoder_state_t sbc_encoder_state;
160 
161 static uint8_t media_sbc_codec_configuration[4];
162 static a2dp_media_sending_context_t media_tracker;
163 
164 static stream_data_source_t data_source;
165 
166 static int sine_phase;
167 
168 static int hxcmod_initialized;
169 static modcontext mod_context;
170 static tracker_buffer_state trkbuf;
171 
172 static uint16_t avrcp_controller_cid = 0;
173 
174 /* AVRCP Target context START */
175 static const uint8_t subunit_info[] = {
176     0,0,0,0,
177     1,1,1,1,
178     2,2,2,2,
179     3,3,3,3,
180     4,4,4,4,
181     5,5,5,5,
182     6,6,6,6,
183     7,7,7,7
184 };
185 
186 static uint32_t company_id = 0x112233;
187 static uint8_t companies_num = 1;
188 static uint8_t companies[] = {
189     0x00, 0x19, 0x58 //BT SIG registered CompanyID
190 };
191 
192 static uint8_t events_num = 13;
193 static uint8_t events[] = {
194     AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED,
195     AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED,
196     AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_END,
197     AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_START,
198     AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED,
199     AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED,
200     AVRCP_NOTIFICATION_EVENT_SYSTEM_STATUS_CHANGED,
201     AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED,
202     AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED,
203     AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED,
204     AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED,
205     AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED,
206     AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED
207 };
208 
209 typedef struct {
210     uint8_t track_id[8];
211     uint32_t song_length_ms;
212     avrcp_playback_status_t status;
213     uint32_t song_position_ms; // 0xFFFFFFFF if not supported
214 } avrcp_play_status_info_t;
215 
216 // python -c "print('a'*512)"
217 static const char title[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
218 
219 avrcp_track_t tracks[] = {
220     {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 1, "Sine", "Generated", "A2DP Source Demo", "monotone", 12345},
221     {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, 2, "Nao-deceased", "Decease", "A2DP Source Demo", "vivid", 12345},
222     {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}, 3, (char *)title, "Decease", "A2DP Source Demo", "vivid", 12345},
223 };
224 int current_track_index;
225 avrcp_play_status_info_t play_info;
226 
227 /* AVRCP Target context END */
228 
229 /* @section Main Application Setup
230  *
231  * @text The Listing MainConfiguration shows how to setup AD2P Source and AVRCP Target services.
232  */
233 
234 /* LISTING_START(MainConfiguration): Setup Audio Source and AVRCP Target services */
235 static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size);
236 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
237 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
238 #ifdef HAVE_BTSTACK_STDIN
239 static void stdin_process(char cmd);
240 #endif
241 
242 static int a2dp_source_and_avrcp_services_init(void){
243 
244     l2cap_init();
245     // Initialize  A2DP Source.
246     a2dp_source_init();
247     a2dp_source_register_packet_handler(&a2dp_source_packet_handler);
248 
249     // Create stream endpoint.
250     avdtp_stream_endpoint_t * local_stream_endpoint = a2dp_source_create_stream_endpoint(AVDTP_AUDIO, AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities), media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration));
251     if (!local_stream_endpoint){
252         printf("A2DP Source: not enough memory to create local stream endpoint\n");
253         return 1;
254     }
255     media_tracker.local_seid = avdtp_local_seid(local_stream_endpoint);
256     avdtp_source_register_delay_reporting_category(media_tracker.local_seid);
257 
258     // Initialize AVRCP Target.
259     avrcp_target_init();
260     avrcp_target_register_packet_handler(&avrcp_target_packet_handler);
261     // Initialize AVRCP Controller
262     avrcp_controller_init();
263     avrcp_controller_register_packet_handler(&avrcp_controller_packet_handler);
264 
265     // Initialize SDP,
266     sdp_init();
267 
268     // Create  A2DP Source service record and register it with SDP.
269     memset(sdp_a2dp_source_service_buffer, 0, sizeof(sdp_a2dp_source_service_buffer));
270     a2dp_source_create_sdp_record(sdp_a2dp_source_service_buffer, 0x10002, 1, NULL, NULL);
271     sdp_register_service(sdp_a2dp_source_service_buffer);
272 
273     // Create AVRCP target service record and register it with SDP.
274     memset(sdp_avrcp_target_service_buffer, 0, sizeof(sdp_avrcp_target_service_buffer));
275     uint16_t supported_features = (1 << AVRCP_TARGET_SUPPORTED_FEATURE_CATEGORY_PLAYER_OR_RECORDER);
276 #ifdef AVRCP_BROWSING_ENABLED
277     supported_features |= (1 << AVRCP_TARGET_SUPPORTED_FEATURE_BROWSING);
278 #endif
279     avrcp_target_create_sdp_record(sdp_avrcp_target_service_buffer, 0x10001, supported_features, NULL, NULL);
280     sdp_register_service(sdp_avrcp_target_service_buffer);
281 
282     // setup AVRCP Controller
283     memset(sdp_avrcp_controller_service_buffer, 0, sizeof(sdp_avrcp_controller_service_buffer));
284     uint16_t controller_supported_features = (1 << AVRCP_CONTROLLER_SUPPORTED_FEATURE_CATEGORY_MONITOR_OR_AMPLIFIER);
285     avrcp_controller_create_sdp_record(sdp_avrcp_controller_service_buffer, 0x10002, controller_supported_features, NULL, NULL);
286     sdp_register_service(sdp_avrcp_controller_service_buffer);
287 
288     // Set local name with a template Bluetooth address, that will be automatically
289     // replaced with a actual address once it is available, i.e. when BTstack boots
290     // up and starts talking to a Bluetooth module.
291     gap_set_local_name("A2DP Source 00:00:00:00:00:00");
292     gap_discoverable_control(1);
293     gap_set_class_of_device(0x200408);
294 
295     // Register for HCI events.
296     hci_event_callback_registration.callback = &a2dp_source_packet_handler;
297     hci_add_event_handler(&hci_event_callback_registration);
298 
299     hxcmod_initialized = hxcmod_init(&mod_context);
300     if (hxcmod_initialized){
301         hxcmod_setcfg(&mod_context, A2DP_SAMPLE_RATE, 16, 1, 1, 1);
302         hxcmod_load(&mod_context, (void *) &mod_data, mod_len);
303         printf("loaded mod '%s', size %u\n", mod_name, mod_len);
304     }
305 
306     // Parse human readable Bluetooth address.
307     sscanf_bd_addr(device_addr_string, device_addr);
308 
309 #ifdef HAVE_BTSTACK_STDIN
310     btstack_stdin_setup(stdin_process);
311 #endif
312     return 0;
313 }
314 /* LISTING_END */
315 
316 static void a2dp_demo_send_media_packet(void){
317     int num_bytes_in_frame = btstack_sbc_encoder_sbc_buffer_length();
318     int bytes_in_storage = media_tracker.sbc_storage_count;
319     uint8_t num_frames = bytes_in_storage / num_bytes_in_frame;
320     a2dp_source_stream_send_media_payload(media_tracker.a2dp_cid, media_tracker.local_seid, media_tracker.sbc_storage, bytes_in_storage, num_frames, 0);
321     media_tracker.sbc_storage_count = 0;
322     media_tracker.sbc_ready_to_send = 0;
323 }
324 
325 static void produce_sine_audio(int16_t * pcm_buffer, int num_samples_to_write){
326     int count;
327     for (count = 0; count < num_samples_to_write ; count++){
328         pcm_buffer[count * 2]     = sine_int16[sine_phase];
329         pcm_buffer[count * 2 + 1] = sine_int16[sine_phase];
330         sine_phase++;
331         if (sine_phase >= TABLE_SIZE_441HZ){
332             sine_phase -= TABLE_SIZE_441HZ;
333         }
334     }
335 }
336 
337 static void produce_mod_audio(int16_t * pcm_buffer, int num_samples_to_write){
338     hxcmod_fillbuffer(&mod_context, (unsigned short *) &pcm_buffer[0], num_samples_to_write, &trkbuf);
339 }
340 
341 static void produce_audio(int16_t * pcm_buffer, int num_samples){
342     switch (data_source){
343         case STREAM_SINE:
344             produce_sine_audio(pcm_buffer, num_samples);
345             break;
346         case STREAM_MOD:
347             produce_mod_audio(pcm_buffer, num_samples);
348             break;
349         default:
350             break;
351     }
352 #ifdef VOLUME_REDUCTION
353     int i;
354     for (i=0;i<num_samples*2;i++){
355         if (pcm_buffer[i] > 0){
356             pcm_buffer[i] =     pcm_buffer[i]  >> VOLUME_REDUCTION;
357         } else {
358             pcm_buffer[i] = -((-pcm_buffer[i]) >> VOLUME_REDUCTION);
359         }
360     }
361 #endif
362 }
363 
364 static int a2dp_demo_fill_sbc_audio_buffer(a2dp_media_sending_context_t * context){
365     // perform sbc encodin
366     int total_num_bytes_read = 0;
367     unsigned int num_audio_samples_per_sbc_buffer = btstack_sbc_encoder_num_audio_frames();
368     while (context->samples_ready >= num_audio_samples_per_sbc_buffer
369         && (context->max_media_payload_size - context->sbc_storage_count) >= btstack_sbc_encoder_sbc_buffer_length()){
370 
371         int16_t pcm_frame[256*NUM_CHANNELS];
372 
373         produce_audio(pcm_frame, num_audio_samples_per_sbc_buffer);
374         btstack_sbc_encoder_process_data(pcm_frame);
375 
376         uint16_t sbc_frame_size = btstack_sbc_encoder_sbc_buffer_length();
377         uint8_t * sbc_frame = btstack_sbc_encoder_sbc_buffer();
378 
379         total_num_bytes_read += num_audio_samples_per_sbc_buffer;
380         memcpy(&context->sbc_storage[context->sbc_storage_count], sbc_frame, sbc_frame_size);
381         context->sbc_storage_count += sbc_frame_size;
382         context->samples_ready -= num_audio_samples_per_sbc_buffer;
383     }
384     return total_num_bytes_read;
385 }
386 
387 static void a2dp_demo_audio_timeout_handler(btstack_timer_source_t * timer){
388     a2dp_media_sending_context_t * context = (a2dp_media_sending_context_t *) btstack_run_loop_get_timer_context(timer);
389     btstack_run_loop_set_timer(&context->audio_timer, AUDIO_TIMEOUT_MS);
390     btstack_run_loop_add_timer(&context->audio_timer);
391     uint32_t now = btstack_run_loop_get_time_ms();
392 
393     uint32_t update_period_ms = AUDIO_TIMEOUT_MS;
394     if (context->time_audio_data_sent > 0){
395         update_period_ms = now - context->time_audio_data_sent;
396     }
397 
398     uint32_t num_samples = (update_period_ms * A2DP_SAMPLE_RATE) / 1000;
399     context->acc_num_missed_samples += (update_period_ms * A2DP_SAMPLE_RATE) % 1000;
400 
401     while (context->acc_num_missed_samples >= 1000){
402         num_samples++;
403         context->acc_num_missed_samples -= 1000;
404     }
405     context->time_audio_data_sent = now;
406     context->samples_ready += num_samples;
407 
408     if (context->sbc_ready_to_send) return;
409 
410     a2dp_demo_fill_sbc_audio_buffer(context);
411 
412     if ((context->sbc_storage_count + btstack_sbc_encoder_sbc_buffer_length()) > context->max_media_payload_size){
413         // schedule sending
414         context->sbc_ready_to_send = 1;
415         a2dp_source_stream_endpoint_request_can_send_now(context->a2dp_cid, context->local_seid);
416     }
417 }
418 
419 static void a2dp_demo_timer_start(a2dp_media_sending_context_t * context){
420     context->max_media_payload_size = btstack_min(a2dp_max_media_payload_size(context->a2dp_cid, context->local_seid), SBC_STORAGE_SIZE);
421     context->sbc_storage_count = 0;
422     context->sbc_ready_to_send = 0;
423     context->streaming = 1;
424     btstack_run_loop_remove_timer(&context->audio_timer);
425     btstack_run_loop_set_timer_handler(&context->audio_timer, a2dp_demo_audio_timeout_handler);
426     btstack_run_loop_set_timer_context(&context->audio_timer, context);
427     btstack_run_loop_set_timer(&context->audio_timer, AUDIO_TIMEOUT_MS);
428     btstack_run_loop_add_timer(&context->audio_timer);
429 }
430 
431 static void a2dp_demo_timer_stop(a2dp_media_sending_context_t * context){
432     context->time_audio_data_sent = 0;
433     context->acc_num_missed_samples = 0;
434     context->samples_ready = 0;
435     context->streaming = 1;
436     context->sbc_storage_count = 0;
437     context->sbc_ready_to_send = 0;
438     btstack_run_loop_remove_timer(&context->audio_timer);
439 }
440 
441 static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t * configuration){
442     printf("Received media codec configuration:\n");
443     printf("    - num_channels: %d\n", configuration->num_channels);
444     printf("    - sampling_frequency: %d\n", configuration->sampling_frequency);
445     printf("    - channel_mode: %d\n", configuration->channel_mode);
446     printf("    - block_length: %d\n", configuration->block_length);
447     printf("    - subbands: %d\n", configuration->subbands);
448     printf("    - allocation_method: %d\n", configuration->allocation_method);
449     printf("    - bitpool_value [%d, %d] \n", configuration->min_bitpool_value, configuration->max_bitpool_value);
450 }
451 
452 static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
453     UNUSED(channel);
454     UNUSED(size);
455     uint8_t status;
456     uint8_t local_seid;
457     bd_addr_t address;
458     uint16_t cid;
459 
460     if (packet_type != HCI_EVENT_PACKET) return;
461 
462 #ifndef HAVE_BTSTACK_STDIN
463     if (hci_event_packet_get_type(packet) == BTSTACK_EVENT_STATE){
464         if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return;
465         printf("Create A2DP Source connection to addr %s.\n", bd_addr_to_str(device_addr));
466         status = a2dp_source_establish_stream(device_addr, media_tracker.local_seid, &media_tracker.a2dp_cid);
467         if (status != ERROR_CODE_SUCCESS){
468             printf("Could not perform command, status 0x%2x\n", status);
469         }
470         return;
471     }
472 #endif
473     if (hci_event_packet_get_type(packet) == HCI_EVENT_PIN_CODE_REQUEST) {
474         printf("Pin code request - using '0000'\n");
475         hci_event_pin_code_request_get_bd_addr(packet, address);
476         gap_pin_code_response(address, "0000");
477         return;
478     }
479 
480     if (hci_event_packet_get_type(packet) != HCI_EVENT_A2DP_META) return;
481 
482     switch (hci_event_a2dp_meta_get_subevent_code(packet)){
483         case A2DP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
484             a2dp_subevent_signaling_connection_established_get_bd_addr(packet, address);
485             cid = a2dp_subevent_signaling_connection_established_get_a2dp_cid(packet);
486             status = a2dp_subevent_signaling_connection_established_get_status(packet);
487 
488             if (status != ERROR_CODE_SUCCESS){
489                 printf("A2DP Source: Connection failed, status 0x%02x, cid 0x%02x, a2dp_cid 0x%02x \n", status, cid, media_tracker.a2dp_cid);
490                 media_tracker.a2dp_cid = 0;
491                 break;
492             }
493             media_tracker.a2dp_cid = cid;
494             printf("A2DP Source: Connected to address %s, a2dp cid 0x%02x.\n", bd_addr_to_str(address), media_tracker.a2dp_cid);
495             break;
496 
497          case A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
498             cid  = avdtp_subevent_signaling_media_codec_sbc_configuration_get_avdtp_cid(packet);
499             if (cid != media_tracker.a2dp_cid) return;
500 
501             sbc_configuration.reconfigure = a2dp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
502             sbc_configuration.num_channels = a2dp_subevent_signaling_media_codec_sbc_configuration_get_num_channels(packet);
503             sbc_configuration.sampling_frequency = a2dp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
504             sbc_configuration.channel_mode = a2dp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
505             sbc_configuration.block_length = a2dp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
506             sbc_configuration.subbands = a2dp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
507             sbc_configuration.allocation_method = a2dp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
508             sbc_configuration.min_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_min_bitpool_value(packet);
509             sbc_configuration.max_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet);
510             sbc_configuration.frames_per_buffer = sbc_configuration.subbands * sbc_configuration.block_length;
511             printf("A2DP Source: Received SBC codec configuration, sampling frequency %u.\n", sbc_configuration.sampling_frequency);
512 
513             // Adapt Bluetooth spec definition to SBC Encoder expected input
514             sbc_configuration.allocation_method -= 1;
515             sbc_configuration.num_channels = 2;
516             switch (sbc_configuration.channel_mode){
517                 case AVDTP_SBC_JOINT_STEREO:
518                     sbc_configuration.channel_mode = 3;
519                     break;
520                 case AVDTP_SBC_STEREO:
521                     sbc_configuration.channel_mode = 2;
522                     break;
523                 case AVDTP_SBC_DUAL_CHANNEL:
524                     sbc_configuration.channel_mode = 1;
525                     break;
526                 case AVDTP_SBC_MONO:
527                     sbc_configuration.channel_mode = 0;
528                     sbc_configuration.num_channels = 1;
529                     break;
530             }
531             dump_sbc_configuration(&sbc_configuration);
532 
533             btstack_sbc_encoder_init(&sbc_encoder_state, SBC_MODE_STANDARD,
534                 sbc_configuration.block_length, sbc_configuration.subbands,
535                 sbc_configuration.allocation_method, sbc_configuration.sampling_frequency,
536                 sbc_configuration.max_bitpool_value,
537                 sbc_configuration.channel_mode);
538             break;
539         }
540 
541         case A2DP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY:
542             printf("A2DP Source: remote supports delay report\n");
543             break;
544         case A2DP_SUBEVENT_SIGNALING_CAPABILITIES_DONE:
545             printf("A2DP Source: All capabilities reported\n");
546             break;
547 
548         case A2DP_SUBEVENT_SIGNALING_DELAY_REPORT:
549             printf("A2DP Source: Received delay report of %d.%0d ms, local seid %d\n",
550                 avdtp_subevent_signaling_delay_report_get_delay_100us(packet)/10, avdtp_subevent_signaling_delay_report_get_delay_100us(packet)%10,
551                 avdtp_subevent_signaling_delay_report_get_local_seid(packet));
552             break;
553 
554         case A2DP_SUBEVENT_STREAM_ESTABLISHED:
555             a2dp_subevent_stream_established_get_bd_addr(packet, address);
556             status = a2dp_subevent_stream_established_get_status(packet);
557             if (status){
558                 printf("A2DP Source: Stream failed, status 0x%02x.\n", status);
559                 break;
560             }
561             local_seid = a2dp_subevent_stream_established_get_local_seid(packet);
562             if (local_seid != media_tracker.local_seid){
563                 printf("A2DP Source: Stream failed, wrong local seid %d, expected %d.\n", local_seid, media_tracker.local_seid);
564                 break;
565             }
566             printf("A2DP Source: Stream established, address %s, a2dp cid 0x%02x, local seid %d, remote seid %d.\n", bd_addr_to_str(address),
567                 media_tracker.a2dp_cid, media_tracker.local_seid, a2dp_subevent_stream_established_get_remote_seid(packet));
568             media_tracker.stream_opened = 1;
569             data_source = STREAM_MOD;
570             status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
571             break;
572 
573         case A2DP_SUBEVENT_STREAM_RECONFIGURED:
574             status = a2dp_subevent_stream_reconfigured_get_status(packet);
575             printf("A2DP Source: Reconfigured, status 0x%02x\n", status);
576             break;
577 
578         case A2DP_SUBEVENT_STREAM_STARTED:
579             play_info.status = AVRCP_PLAYBACK_STATUS_PLAYING;
580             if (media_tracker.avrcp_cid){
581                 avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t));
582                 avrcp_target_set_playback_status(media_tracker.avrcp_cid, AVRCP_PLAYBACK_STATUS_PLAYING);
583             }
584             a2dp_demo_timer_start(&media_tracker);
585             printf("A2DP Source: Stream started.\n");
586             break;
587 
588         case A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW:
589             a2dp_demo_send_media_packet();
590             break;
591 
592         case A2DP_SUBEVENT_STREAM_SUSPENDED:
593             play_info.status = AVRCP_PLAYBACK_STATUS_PAUSED;
594             if (media_tracker.avrcp_cid){
595                 avrcp_target_set_playback_status(media_tracker.avrcp_cid, AVRCP_PLAYBACK_STATUS_PAUSED);
596             }
597             printf("A2DP Source: Stream paused.\n");
598             a2dp_demo_timer_stop(&media_tracker);
599             break;
600 
601         case A2DP_SUBEVENT_STREAM_RELEASED:
602             play_info.status = AVRCP_PLAYBACK_STATUS_STOPPED;
603             cid = a2dp_subevent_stream_released_get_a2dp_cid(packet);
604             if (cid == media_tracker.a2dp_cid) {
605                 media_tracker.stream_opened = 0;
606                 printf("A2DP Source: Stream released.\n");
607             }
608             if (media_tracker.avrcp_cid){
609                 avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, NULL, sizeof(tracks)/sizeof(avrcp_track_t));
610                 avrcp_target_set_playback_status(media_tracker.avrcp_cid, AVRCP_PLAYBACK_STATUS_STOPPED);
611             }
612             a2dp_demo_timer_stop(&media_tracker);
613             break;
614         case A2DP_SUBEVENT_SIGNALING_CONNECTION_RELEASED:
615             cid = a2dp_subevent_signaling_connection_released_get_a2dp_cid(packet);
616             if (cid == media_tracker.a2dp_cid) {
617                 media_tracker.avrcp_cid = 0;
618                 media_tracker.a2dp_cid = 0;
619                 printf("A2DP Source: Signaling released.\n\n");
620             }
621             break;
622         default:
623             break;
624     }
625 }
626 
627 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
628     UNUSED(channel);
629     UNUSED(size);
630     bd_addr_t event_addr;
631     uint16_t local_cid;
632     uint8_t  status = ERROR_CODE_SUCCESS;
633 
634     if (packet_type != HCI_EVENT_PACKET) return;
635     if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
636 
637     switch (packet[2]){
638         case AVRCP_SUBEVENT_CONNECTION_ESTABLISHED: {
639             local_cid = avrcp_subevent_connection_established_get_avrcp_cid(packet);
640             // if (avrcp_cid != 0 && avrcp_cid != local_cid) {
641             //     printf("AVRCP Target: Connection failed, expected 0x%02X l2cap cid, received 0x%02X\n", avrcp_cid, local_cid);
642             //     return;
643             // }
644             // if (avrcp_cid != local_cid) break;
645 
646             status = avrcp_subevent_connection_established_get_status(packet);
647             if (status != ERROR_CODE_SUCCESS){
648                 printf("AVRCP Target: Connection failed, status 0x%02x\n", status);
649                 return;
650             }
651             media_tracker.avrcp_cid = local_cid;
652             avrcp_subevent_connection_established_get_bd_addr(packet, event_addr);
653             printf("AVRCP Target: Connected to %s, avrcp_cid 0x%02x\n", bd_addr_to_str(event_addr), local_cid);
654 
655             avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, NULL, sizeof(tracks)/sizeof(avrcp_track_t));
656             avrcp_target_set_unit_info(media_tracker.avrcp_cid, AVRCP_SUBUNIT_TYPE_AUDIO, company_id);
657             avrcp_target_set_subunit_info(media_tracker.avrcp_cid, AVRCP_SUBUNIT_TYPE_AUDIO, (uint8_t *)subunit_info, sizeof(subunit_info));
658             return;
659         }
660         case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:
661             printf("AVRCP Target: new volume %d\n", avrcp_subevent_notification_volume_changed_get_absolute_volume(packet));
662             break;
663         case AVRCP_SUBEVENT_EVENT_IDS_QUERY:
664             status = avrcp_target_supported_events(media_tracker.avrcp_cid, events_num, events, sizeof(events));
665             break;
666         case AVRCP_SUBEVENT_COMPANY_IDS_QUERY:
667             status = avrcp_target_supported_companies(media_tracker.avrcp_cid, companies_num, companies, sizeof(companies));
668             break;
669         case AVRCP_SUBEVENT_PLAY_STATUS_QUERY:
670             status = avrcp_target_play_status(media_tracker.avrcp_cid, play_info.song_length_ms, play_info.song_position_ms, play_info.status);
671             break;
672         // case AVRCP_SUBEVENT_NOW_PLAYING_INFO_QUERY:
673         //     status = avrcp_target_now_playing_info(avrcp_cid);
674         //     break;
675         case AVRCP_SUBEVENT_OPERATION:{
676             avrcp_operation_id_t operation_id = avrcp_subevent_operation_get_operation_id(packet);
677             switch (operation_id){
678                 case AVRCP_OPERATION_ID_PLAY:
679                     printf("AVRCP Target: PLAY\n");
680                     status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
681                     break;
682                 case AVRCP_OPERATION_ID_PAUSE:
683                     printf("AVRCP Target: PAUSE\n");
684                     status = a2dp_source_pause_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
685                     break;
686                 case AVRCP_OPERATION_ID_STOP:
687                     printf("AVRCP Target: STOP\n");
688                     status = a2dp_source_disconnect(media_tracker.a2dp_cid);
689                     break;
690                 default:
691                     printf("AVRCP Target: operation 0x%2x is not handled\n", operation_id);
692                     return;
693             }
694             break;
695         }
696         case AVRCP_SUBEVENT_CONNECTION_RELEASED:
697             printf("AVRCP Target: Disconnected, avrcp_cid 0x%02x\n", avrcp_subevent_connection_released_get_avrcp_cid(packet));
698             media_tracker.avrcp_cid = 0;
699             return;
700         default:
701             break;
702     }
703 
704     if (status != ERROR_CODE_SUCCESS){
705         printf("Responding to event 0x%02x failed with status 0x%02x\n", packet[2], status);
706     }
707 }
708 
709 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
710     UNUSED(channel);
711     UNUSED(size);
712     uint16_t local_cid;
713     uint8_t  status = 0xFF;
714     bd_addr_t adress;
715 
716     if (packet_type != HCI_EVENT_PACKET) return;
717     if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
718     switch (packet[2]){
719         case AVRCP_SUBEVENT_CONNECTION_ESTABLISHED: {
720             local_cid = avrcp_subevent_connection_established_get_avrcp_cid(packet);
721             if (avrcp_controller_cid != 0 && avrcp_controller_cid != local_cid) {
722                 printf("AVRCP Controller: Connection failed, expected 0x%02X l2cap cid, received 0x%02X\n", avrcp_controller_cid, local_cid);
723                 return;
724             }
725 
726             status = avrcp_subevent_connection_established_get_status(packet);
727             if (status != ERROR_CODE_SUCCESS){
728                 printf("AVRCP Controller: Connection failed: status 0x%02x\n", status);
729                 avrcp_controller_cid = 0;
730                 return;
731             }
732 
733             avrcp_controller_cid = local_cid;
734             avrcp_subevent_connection_established_get_bd_addr(packet, adress);
735             printf("AVRCP Controller: Channel successfully opened: %s, avrcp_controller_cid 0x%02x\n", bd_addr_to_str(adress), avrcp_controller_cid);
736 
737             // automatically enable notifications
738             avrcp_controller_enable_notification(avrcp_controller_cid, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED);
739             return;
740         }
741         case AVRCP_SUBEVENT_CONNECTION_RELEASED:
742             printf("AVRCP Controller: Channel released: avrcp_controller_cid 0x%02x\n", avrcp_subevent_connection_released_get_avrcp_cid(packet));
743             avrcp_controller_cid = 0;
744             return;
745         default:
746             break;
747     }
748 
749     status = packet[5];
750     if (!avrcp_controller_cid) return;
751 
752     // ignore INTERIM status
753     if (status == AVRCP_CTYPE_RESPONSE_INTERIM) return;
754 
755     switch (packet[2]){
756         case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:{
757             int volume_percentage = avrcp_subevent_notification_volume_changed_get_absolute_volume(packet) * 100 / 127;
758             printf("AVRCP Controller: notification absolute volume changed %d %%\n", volume_percentage);
759             return;
760         }
761         default:
762             break;
763     }
764 }
765 
766 #ifdef HAVE_BTSTACK_STDIN
767 static void show_usage(void){
768     bd_addr_t      iut_address;
769     gap_local_bd_addr(iut_address);
770     printf("\n--- Bluetooth  A2DP Source/AVRCP Target Demo %s ---\n", bd_addr_to_str(iut_address));
771     printf("b      - A2DP Source create connection to addr %s\n", device_addr_string);
772     printf("B      - A2DP Source disconnect\n");
773     printf("c      - AVRCP Target create connection to addr %s\n", device_addr_string);
774     printf("C      - AVRCP Target disconnect\n");
775 
776     printf("x      - start streaming sine\n");
777     if (hxcmod_initialized){
778         printf("z      - start streaming '%s'\n", mod_name);
779     }
780     printf("p      - pause streaming\n");
781     printf("w      - reconfigure stream for 44100 Hz\n");
782     printf("e      - reconfigure stream for 48000 Hz\n");
783     printf("t      - volume up\n");
784     printf("T      - volume down\n");
785     printf("v      - absolute volume of 50 percent\n");
786 
787     printf("\n--- Bluetooth  AVRCP Target Commands %s ---\n", bd_addr_to_str(iut_address));
788     printf("---\n");
789 }
790 
791 static void stdin_process(char cmd){
792     uint8_t status = ERROR_CODE_SUCCESS;
793     switch (cmd){
794         case 'b':
795             status = a2dp_source_establish_stream(device_addr, media_tracker.local_seid, &media_tracker.a2dp_cid);
796             printf("%c - Create A2DP Source connection to addr %s, cid 0x%02x.\n", cmd, bd_addr_to_str(device_addr), media_tracker.a2dp_cid);
797             break;
798         case 'B':
799             printf("%c - A2DP Source Disconnect from cid 0x%2x\n", cmd, media_tracker.a2dp_cid);
800             status = a2dp_source_disconnect(media_tracker.a2dp_cid);
801             break;
802         case 'c':
803             printf("%c - Create AVRCP Target connection to addr %s.\n", cmd, bd_addr_to_str(device_addr));
804             status = avrcp_target_connect(device_addr, &media_tracker.avrcp_cid);
805             break;
806         case 'C':
807             printf("%c - AVRCP Target disconnect\n", cmd);
808             status = avrcp_target_disconnect(media_tracker.avrcp_cid);
809             break;
810 
811         case '\n':
812         case '\r':
813             break;
814 
815         case 't':
816             printf(" - volume up\n");
817             status = avrcp_controller_volume_up(avrcp_controller_cid);
818             break;
819         case 'T':
820             printf(" - volume down\n");
821             status = avrcp_controller_volume_down(avrcp_controller_cid);
822             break;
823         case 'v':
824             printf(" - absolute volume of 50%% (64)\n");
825             status = avrcp_controller_set_absolute_volume(avrcp_controller_cid, 64);
826             break;
827 
828         case 'x':
829             if (media_tracker.avrcp_cid){
830                 avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t));
831             }
832             printf("%c - Play sine.\n", cmd);
833             data_source = STREAM_SINE;
834             if (!media_tracker.stream_opened) break;
835             status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
836             break;
837         case 'z':
838             if (media_tracker.avrcp_cid){
839                 avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t));
840             }
841             printf("%c - Play mod.\n", cmd);
842             data_source = STREAM_MOD;
843             if (!media_tracker.stream_opened) break;
844             status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
845             break;
846 
847         case 'p':
848             if (!media_tracker.stream_opened) break;
849             printf("%c - Pause stream.\n", cmd);
850             status = a2dp_source_pause_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
851             break;
852 
853         case 'w':
854             if (!media_tracker.stream_opened) break;
855             if (play_info.status == AVRCP_PLAYBACK_STATUS_PLAYING){
856                 printf("Stream cannot be reconfigured while playing, please pause stream first\n");
857                 break;
858             }
859             printf("%c - Reconfigure for 44100 Hz.\n", cmd);
860             status = a2dp_source_reconfigure_stream_sampling_frequency(media_tracker.a2dp_cid, 44100);
861             break;
862 
863         case 'e':
864             if (!media_tracker.stream_opened) break;
865             if (play_info.status == AVRCP_PLAYBACK_STATUS_PLAYING){
866                 printf("Stream cannot be reconfigured while playing, please pause stream first\n");
867                 break;
868             }
869             printf("%c - Reconfigure for 48000 Hz.\n", cmd);
870             status = a2dp_source_reconfigure_stream_sampling_frequency(media_tracker.a2dp_cid, 48000);
871             break;
872 
873         default:
874             show_usage();
875             return;
876     }
877     if (status != ERROR_CODE_SUCCESS){
878         printf("Could not perform command \'%c\', status 0x%2x\n", cmd, status);
879     }
880 }
881 #endif
882 
883 
884 int btstack_main(int argc, const char * argv[]);
885 int btstack_main(int argc, const char * argv[]){
886     (void)argc;
887     (void)argv;
888 
889     int err = a2dp_source_and_avrcp_services_init();
890     if (err) return err;
891     // turn on!
892     hci_power_control(HCI_POWER_ON);
893     return 0;
894 }
895 /* EXAMPLE_END */
896