a2dp_sink_demo.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121
  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. * contact@bluekitchen-gmbh.com
  35. *
  36. */
  37. #define BTSTACK_FILE__ "a2dp_sink_demo.c"
  38. /*
  39. * a2dp_sink_demo.c
  40. */
  41. // *****************************************************************************
  42. /* EXAMPLE_START(a2dp_sink_demo): Receive audio stream and control its playback.
  43. *
  44. * @text This A2DP Sink example demonstrates how to use the A2DP Sink service to
  45. * receive an audio data stream from a remote A2DP Source device. In addition,
  46. * the AVRCP Controller is used to get information on currently played media,
  47. * such are title, artist and album, as well as to control the playback,
  48. * i.e. to play, stop, repeat, etc. If HAVE_BTSTACK_STDIN is set, press SPACE on
  49. * the console to show the available AVDTP and AVRCP commands.
  50. *
  51. * @text To test with a remote device, e.g. a mobile phone,
  52. * pair from the remote device with the demo, then start playing music on the remote device.
  53. * Alternatively, set the device_addr_string to the Bluetooth address of your
  54. * remote device in the code, and call connect from the UI.
  55. *
  56. * @text For more info on BTstack audio, see our blog post
  57. * [A2DP Sink and Source on STM32 F4 Discovery Board](http://bluekitchen-gmbh.com/a2dp-sink-and-source-on-stm32-f4-discovery-board/).
  58. *
  59. */
  60. // *****************************************************************************
  61. #include <inttypes.h>
  62. #include <stdint.h>
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. #include <string.h>
  66. #include "btstack.h"
  67. #include "btstack_resample.h"
  68. //#define AVRCP_BROWSING_ENABLED
  69. // if volume control not supported by btstack_audio_sink, you can try to disable volume change notification
  70. // to force the A2DP Source to reduce volume by attenuating the audio stream
  71. #define SUPPORT_VOLUME_CHANGE_NOTIFICATION
  72. #ifdef HAVE_BTSTACK_STDIN
  73. #include "btstack_stdin.h"
  74. #endif
  75. #include "btstack_ring_buffer.h"
  76. #ifdef HAVE_POSIX_FILE_IO
  77. #include "wav_util.h"
  78. #define STORE_TO_SBC_FILE
  79. #define STORE_TO_WAV_FILE
  80. #endif
  81. #define NUM_CHANNELS 2
  82. #define BYTES_PER_FRAME (2*NUM_CHANNELS)
  83. #define MAX_SBC_FRAME_SIZE 120
  84. // SBC Decoder for WAV file or live playback
  85. static btstack_sbc_decoder_state_t state;
  86. static btstack_sbc_mode_t mode = SBC_MODE_STANDARD;
  87. // ring buffer for SBC Frames
  88. // below 30: add samples, 30-40: fine, above 40: drop samples
  89. #define OPTIMAL_FRAMES_MIN 30
  90. #define OPTIMAL_FRAMES_MAX 40
  91. #define ADDITIONAL_FRAMES 20
  92. static uint8_t sbc_frame_storage[(OPTIMAL_FRAMES_MAX + ADDITIONAL_FRAMES) * MAX_SBC_FRAME_SIZE];
  93. static btstack_ring_buffer_t sbc_frame_ring_buffer;
  94. static unsigned int sbc_frame_size;
  95. // rest buffer for not fully used sbc frames, with additional frames for resampling
  96. static uint8_t decoded_audio_storage[(128+16) * BYTES_PER_FRAME];
  97. static btstack_ring_buffer_t decoded_audio_ring_buffer;
  98. static int audio_stream_started;
  99. // temp storage of lower-layer request
  100. static int16_t * request_buffer;
  101. static int request_frames;
  102. #define STORE_FROM_PLAYBACK
  103. // WAV File
  104. #ifdef STORE_TO_WAV_FILE
  105. static uint32_t audio_frame_count = 0;
  106. static char * wav_filename = "av2dp_sink_demo.wav";
  107. #endif
  108. #ifdef STORE_TO_SBC_FILE
  109. static FILE * sbc_file;
  110. static char * sbc_filename = "av2dp_sink_demo.sbc";
  111. #endif
  112. typedef struct {
  113. int reconfigure;
  114. int num_channels;
  115. int sampling_frequency;
  116. int channel_mode;
  117. int block_length;
  118. int subbands;
  119. int allocation_method;
  120. int min_bitpool_value;
  121. int max_bitpool_value;
  122. int frames_per_buffer;
  123. } avdtp_media_codec_configuration_sbc_t;
  124. static avdtp_media_codec_configuration_sbc_t sbc_configuration;
  125. static int volume_percentage = 0;
  126. #ifdef SUPPORT_VOLUME_CHANGE_NOTIFICATION
  127. static uint8_t events_num = 3;
  128. static uint8_t events[] = {
  129. AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED,
  130. AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED,
  131. AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED
  132. };
  133. #endif
  134. static uint8_t companies_num = 1;
  135. static uint8_t companies[] = {
  136. 0x00, 0x19, 0x58 //BT SIG registered CompanyID
  137. };
  138. #ifdef HAVE_BTSTACK_STDIN
  139. // pts:
  140. static const char * device_addr_string = "6C:72:E7:10:22:EE";
  141. // mac 2013: static const char * device_addr_string = "84:38:35:65:d1:15";
  142. // iPhone 5S: static const char * device_addr_string = "54:E4:3A:26:A2:39";
  143. static bd_addr_t device_addr;
  144. #endif
  145. static btstack_packet_callback_registration_t hci_event_callback_registration;
  146. static uint8_t sdp_avdtp_sink_service_buffer[150];
  147. static uint8_t sdp_avrcp_target_service_buffer[150];
  148. static uint8_t sdp_avrcp_controller_service_buffer[200];
  149. static uint16_t a2dp_cid = 0;
  150. static uint8_t a2dp_local_seid = 0;
  151. static uint16_t avrcp_cid = 0;
  152. static uint8_t avrcp_connected = 0;
  153. static uint8_t avrcp_subevent_value[100];
  154. static uint8_t media_sbc_codec_capabilities[] = {
  155. 0xFF,//(AVDTP_SBC_44100 << 4) | AVDTP_SBC_STEREO,
  156. 0xFF,//(AVDTP_SBC_BLOCK_LENGTH_16 << 4) | (AVDTP_SBC_SUBBANDS_8 << 2) | AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS,
  157. 2, 53
  158. };
  159. static uint8_t media_sbc_codec_configuration[] = {
  160. (AVDTP_SBC_44100 << 4) | AVDTP_SBC_STEREO,
  161. (AVDTP_SBC_BLOCK_LENGTH_16 << 4) | (AVDTP_SBC_SUBBANDS_8 << 2) | AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS,
  162. 2, 53
  163. };
  164. static int media_initialized = 0;
  165. static btstack_resample_t resample_instance;
  166. /* @section Main Application Setup
  167. *
  168. * @text The Listing MainConfiguration shows how to setup AD2P Sink and AVRCP services.
  169. * Besides calling init() method for each service, you'll also need to register several packet handlers:
  170. * - hci_packet_handler - handles legacy pairing, here by using fixed '0000' pin code.
  171. * - a2dp_sink_packet_handler - handles events on stream connection status (established, released), the media codec configuration, and, the status of the stream itself (opened, paused, stopped).
  172. * - handle_l2cap_media_data_packet - used to receive streaming data. If STORE_TO_WAV_FILE directive (check btstack_config.h) is used, the SBC decoder will be used to decode the SBC data into PCM frames. The resulting PCM frames are then processed in the SBC Decoder callback.
  173. * - avrcp_packet_handler - receives connect/disconnect event.
  174. * - avrcp_controller_packet_handler - receives answers for sent AVRCP commands.
  175. * - avrcp_target_packet_handler - receives AVRCP commands, and registered notifications.
  176. * - stdin_process - used to trigger AVRCP commands to the A2DP Source device, such are get now playing info, start, stop, volume control. Requires HAVE_BTSTACK_STDIN.
  177. *
  178. * @text To announce A2DP Sink and AVRCP services, you need to create corresponding
  179. * SDP records and register them with the SDP service.
  180. *
  181. * @text Note, currently only the SBC codec is supported.
  182. * If you want to store the audio data in a file, you'll need to define STORE_TO_WAV_FILE.
  183. * If STORE_TO_WAV_FILE directive is defined, the SBC decoder needs to get initialized when a2dp_sink_packet_handler receives event A2DP_SUBEVENT_STREAM_STARTED.
  184. * The initialization of the SBC decoder requires a callback that handles PCM data:
  185. * - handle_pcm_data - handles PCM audio frames. Here, they are stored a in wav file if STORE_TO_WAV_FILE is defined, and/or played using the audio library.
  186. */
  187. /* LISTING_START(MainConfiguration): Setup Audio Sink and AVRCP Controller services */
  188. static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
  189. static void a2dp_sink_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size);
  190. static void handle_l2cap_media_data_packet(uint8_t seid, uint8_t *packet, uint16_t size);
  191. static void avrcp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
  192. static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
  193. static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
  194. #ifdef HAVE_BTSTACK_STDIN
  195. static void stdin_process(char cmd);
  196. #endif
  197. static int a2dp_and_avrcp_setup(void){
  198. l2cap_init();
  199. // Initialize AVDTP Sink
  200. a2dp_sink_init();
  201. a2dp_sink_register_packet_handler(&a2dp_sink_packet_handler);
  202. a2dp_sink_register_media_handler(&handle_l2cap_media_data_packet);
  203. avdtp_stream_endpoint_t * local_stream_endpoint = a2dp_sink_create_stream_endpoint(AVDTP_AUDIO,
  204. AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities),
  205. media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration));
  206. if (!local_stream_endpoint){
  207. printf("A2DP Sink: not enough memory to create local stream endpoint\n");
  208. return 1;
  209. }
  210. a2dp_local_seid = avdtp_local_seid(local_stream_endpoint);
  211. // Initialize AVRCP service.
  212. avrcp_init();
  213. avrcp_register_packet_handler(&avrcp_packet_handler);
  214. // Initialize AVRCP Controller
  215. avrcp_controller_init();
  216. avrcp_controller_register_packet_handler(&avrcp_controller_packet_handler);
  217. // Initialize AVRCP Target
  218. avrcp_target_init();
  219. avrcp_target_register_packet_handler(&avrcp_target_packet_handler);
  220. // Initialize SDP
  221. sdp_init();
  222. // setup AVDTP sink
  223. memset(sdp_avdtp_sink_service_buffer, 0, sizeof(sdp_avdtp_sink_service_buffer));
  224. a2dp_sink_create_sdp_record(sdp_avdtp_sink_service_buffer, 0x10001, AVDTP_SINK_FEATURE_MASK_HEADPHONE, NULL, NULL);
  225. sdp_register_service(sdp_avdtp_sink_service_buffer);
  226. // setup AVRCP Controller
  227. memset(sdp_avrcp_controller_service_buffer, 0, sizeof(sdp_avrcp_controller_service_buffer));
  228. uint16_t controller_supported_features = AVRCP_FEATURE_MASK_CATEGORY_PLAYER_OR_RECORDER;
  229. #ifdef AVRCP_BROWSING_ENABLED
  230. controller_supported_features |= AVRCP_FEATURE_MASK_BROWSING;
  231. #endif
  232. avrcp_controller_create_sdp_record(sdp_avrcp_controller_service_buffer, 0x10002, controller_supported_features, NULL, NULL);
  233. sdp_register_service(sdp_avrcp_controller_service_buffer);
  234. // setup AVRCP Target
  235. memset(sdp_avrcp_target_service_buffer, 0, sizeof(sdp_avrcp_target_service_buffer));
  236. uint16_t target_supported_features = AVRCP_FEATURE_MASK_CATEGORY_MONITOR_OR_AMPLIFIER;
  237. avrcp_target_create_sdp_record(sdp_avrcp_target_service_buffer, 0x10003, target_supported_features, NULL, NULL);
  238. sdp_register_service(sdp_avrcp_target_service_buffer);
  239. gap_set_local_name("A2DP Sink Demo 00:00:00:00:00:00");
  240. gap_discoverable_control(1);
  241. gap_set_class_of_device(0x200408);
  242. /* Register for HCI events */
  243. hci_event_callback_registration.callback = &hci_packet_handler;
  244. hci_add_event_handler(&hci_event_callback_registration);
  245. #ifdef HAVE_POSIX_FILE_IO
  246. if (!btstack_audio_sink_get_instance()){
  247. printf("No audio playback.\n");
  248. } else {
  249. printf("Audio playback supported.\n");
  250. }
  251. #ifdef STORE_TO_WAV_FILE
  252. printf("Audio will be stored to \'%s\' file.\n", wav_filename);
  253. #endif
  254. #endif
  255. return 0;
  256. }
  257. /* LISTING_END */
  258. static void playback_handler(int16_t * buffer, uint16_t num_audio_frames){
  259. #ifdef STORE_TO_WAV_FILE
  260. int wav_samples = num_audio_frames * NUM_CHANNELS;
  261. int16_t * wav_buffer = buffer;
  262. #endif
  263. // called from lower-layer but guaranteed to be on main thread
  264. if (sbc_frame_size == 0){
  265. memset(buffer, 0, num_audio_frames * BYTES_PER_FRAME);
  266. return;
  267. }
  268. // first fill from resampled audio
  269. uint32_t bytes_read;
  270. btstack_ring_buffer_read(&decoded_audio_ring_buffer, (uint8_t *) buffer, num_audio_frames * BYTES_PER_FRAME, &bytes_read);
  271. buffer += bytes_read / NUM_CHANNELS;
  272. num_audio_frames -= bytes_read / BYTES_PER_FRAME;
  273. // then start decoding sbc frames using request_* globals
  274. request_buffer = buffer;
  275. request_frames = num_audio_frames;
  276. while (request_frames && btstack_ring_buffer_bytes_available(&sbc_frame_ring_buffer) >= sbc_frame_size){
  277. // decode frame
  278. uint8_t sbc_frame[MAX_SBC_FRAME_SIZE];
  279. btstack_ring_buffer_read(&sbc_frame_ring_buffer, sbc_frame, sbc_frame_size, &bytes_read);
  280. btstack_sbc_decoder_process_data(&state, 0, sbc_frame, sbc_frame_size);
  281. }
  282. #ifdef STORE_TO_WAV_FILE
  283. audio_frame_count += num_audio_frames;
  284. wav_writer_write_int16(wav_samples, wav_buffer);
  285. #endif
  286. }
  287. static void handle_pcm_data(int16_t * data, int num_audio_frames, int num_channels, int sample_rate, void * context){
  288. UNUSED(sample_rate);
  289. UNUSED(context);
  290. UNUSED(num_channels); // must be stereo == 2
  291. const btstack_audio_sink_t * audio_sink = btstack_audio_sink_get_instance();
  292. if (!audio_sink){
  293. #ifdef STORE_TO_WAV_FILE
  294. audio_frame_count += num_audio_frames;
  295. wav_writer_write_int16(num_audio_frames * NUM_CHANNELS, data);
  296. #endif
  297. return;
  298. }
  299. // resample into request buffer - add some additional space for resampling
  300. int16_t output_buffer[(128+16) * NUM_CHANNELS]; // 16 * 8 * 2
  301. uint32_t resampled_frames = btstack_resample_block(&resample_instance, data, num_audio_frames, output_buffer);
  302. // store data in btstack_audio buffer first
  303. int frames_to_copy = btstack_min(resampled_frames, request_frames);
  304. memcpy(request_buffer, output_buffer, frames_to_copy * BYTES_PER_FRAME);
  305. request_frames -= frames_to_copy;
  306. request_buffer += frames_to_copy * NUM_CHANNELS;
  307. // and rest in ring buffer
  308. int frames_to_store = resampled_frames - frames_to_copy;
  309. if (frames_to_store){
  310. int status = btstack_ring_buffer_write(&decoded_audio_ring_buffer, (uint8_t *)&output_buffer[frames_to_copy * NUM_CHANNELS], frames_to_store * BYTES_PER_FRAME);
  311. if (status){
  312. printf("Error storing samples in PCM ring buffer!!!\n");
  313. }
  314. }
  315. }
  316. static int media_processing_init(avdtp_media_codec_configuration_sbc_t configuration){
  317. if (media_initialized) return 0;
  318. btstack_sbc_decoder_init(&state, mode, handle_pcm_data, NULL);
  319. #ifdef STORE_TO_WAV_FILE
  320. wav_writer_open(wav_filename, configuration.num_channels, configuration.sampling_frequency);
  321. #endif
  322. #ifdef STORE_TO_SBC_FILE
  323. sbc_file = fopen(sbc_filename, "wb");
  324. #endif
  325. btstack_ring_buffer_init(&sbc_frame_ring_buffer, sbc_frame_storage, sizeof(sbc_frame_storage));
  326. btstack_ring_buffer_init(&decoded_audio_ring_buffer, decoded_audio_storage, sizeof(decoded_audio_storage));
  327. btstack_resample_init(&resample_instance, configuration.num_channels);
  328. // setup audio playback
  329. const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
  330. if (audio){
  331. audio->init(NUM_CHANNELS, configuration.sampling_frequency, &playback_handler);
  332. }
  333. audio_stream_started = 0;
  334. media_initialized = 1;
  335. return 0;
  336. }
  337. static void media_processing_start(void){
  338. if (!media_initialized) return;
  339. // setup audio playback
  340. const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
  341. if (audio){
  342. audio->start_stream();
  343. }
  344. audio_stream_started = 1;
  345. }
  346. static void media_processing_pause(void){
  347. if (!media_initialized) return;
  348. // stop audio playback
  349. audio_stream_started = 0;
  350. const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
  351. if (audio){
  352. audio->stop_stream();
  353. }
  354. }
  355. static void media_processing_close(void){
  356. if (!media_initialized) return;
  357. media_initialized = 0;
  358. audio_stream_started = 0;
  359. sbc_frame_size = 0;
  360. #ifdef STORE_TO_WAV_FILE
  361. wav_writer_close();
  362. uint32_t total_frames_nr = state.good_frames_nr + state.bad_frames_nr + state.zero_frames_nr;
  363. printf("WAV Writer: Decoding done. Processed %u SBC frames:\n - %d good\n - %d bad\n", total_frames_nr, state.good_frames_nr, total_frames_nr - state.good_frames_nr);
  364. printf("WAV Writer: Wrote %u audio frames to wav file: %s\n", audio_frame_count, wav_filename);
  365. #endif
  366. #ifdef STORE_TO_SBC_FILE
  367. fclose(sbc_file);
  368. #endif
  369. // stop audio playback
  370. const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
  371. if (audio){
  372. printf("close stream\n");
  373. audio->close();
  374. }
  375. }
  376. /* @section Handle Media Data Packet
  377. *
  378. * @text Media data packets, in this case the audio data, are received through the handle_l2cap_media_data_packet callback.
  379. * Currently, only the SBC media codec is supported. Hence, the media data consists of the media packet header and the SBC packet.
  380. * The SBC frame will be stored in a ring buffer for later processing (instead of decoding it to PCM right away which would require a much larger buffer)
  381. * If the audio stream wasn't started already and there are enough SBC frames in the ring buffer, start playback.
  382. */
  383. static int read_media_data_header(uint8_t * packet, int size, int * offset, avdtp_media_packet_header_t * media_header);
  384. static int read_sbc_header(uint8_t * packet, int size, int * offset, avdtp_sbc_codec_header_t * sbc_header);
  385. static void handle_l2cap_media_data_packet(uint8_t seid, uint8_t *packet, uint16_t size){
  386. UNUSED(seid);
  387. int pos = 0;
  388. avdtp_media_packet_header_t media_header;
  389. if (!read_media_data_header(packet, size, &pos, &media_header)) return;
  390. avdtp_sbc_codec_header_t sbc_header;
  391. if (!read_sbc_header(packet, size, &pos, &sbc_header)) return;
  392. #ifdef STORE_TO_SBC_FILE
  393. fwrite(packet+pos, size-pos, 1, sbc_file);
  394. #endif
  395. const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
  396. // process data right away if there's no audio implementation active, e.g. on posix systems to store as .wav
  397. if (!audio){
  398. btstack_sbc_decoder_process_data(&state, 0, packet+pos, size-pos);
  399. return;
  400. }
  401. // store sbc frame size for buffer management
  402. sbc_frame_size = (size-pos)/ sbc_header.num_frames;
  403. int status = btstack_ring_buffer_write(&sbc_frame_ring_buffer, packet+pos, size-pos);
  404. if (status){
  405. printf("Error storing samples in SBC ring buffer!!!\n");
  406. }
  407. // decide on audio sync drift based on number of sbc frames in queue
  408. int sbc_frames_in_buffer = btstack_ring_buffer_bytes_available(&sbc_frame_ring_buffer) / sbc_frame_size;
  409. uint32_t resampling_factor;
  410. // nomimal factor (fixed-point 2^16) and compensation offset
  411. uint32_t nomimal_factor = 0x10000;
  412. uint32_t compensation = 0x00100;
  413. if (sbc_frames_in_buffer < OPTIMAL_FRAMES_MIN){
  414. resampling_factor = nomimal_factor - compensation; // stretch samples
  415. } else if (sbc_frames_in_buffer <= OPTIMAL_FRAMES_MAX){
  416. resampling_factor = nomimal_factor; // nothing to do
  417. } else {
  418. resampling_factor = nomimal_factor + compensation; // compress samples
  419. }
  420. btstack_resample_set_factor(&resample_instance, resampling_factor);
  421. // start stream if enough frames buffered
  422. if (!audio_stream_started && sbc_frames_in_buffer >= OPTIMAL_FRAMES_MIN){
  423. audio_stream_started = 1;
  424. // setup audio playback
  425. if (audio){
  426. audio->start_stream();
  427. }
  428. }
  429. }
  430. static int read_sbc_header(uint8_t * packet, int size, int * offset, avdtp_sbc_codec_header_t * sbc_header){
  431. int sbc_header_len = 12; // without crc
  432. int pos = *offset;
  433. if (size - pos < sbc_header_len){
  434. printf("Not enough data to read SBC header, expected %d, received %d\n", sbc_header_len, size-pos);
  435. return 0;
  436. }
  437. sbc_header->fragmentation = get_bit16(packet[pos], 7);
  438. sbc_header->starting_packet = get_bit16(packet[pos], 6);
  439. sbc_header->last_packet = get_bit16(packet[pos], 5);
  440. sbc_header->num_frames = packet[pos] & 0x0f;
  441. pos++;
  442. *offset = pos;
  443. return 1;
  444. }
  445. static int read_media_data_header(uint8_t *packet, int size, int *offset, avdtp_media_packet_header_t *media_header){
  446. int media_header_len = 12; // without crc
  447. int pos = *offset;
  448. if (size - pos < media_header_len){
  449. printf("Not enough data to read media packet header, expected %d, received %d\n", media_header_len, size-pos);
  450. return 0;
  451. }
  452. media_header->version = packet[pos] & 0x03;
  453. media_header->padding = get_bit16(packet[pos],2);
  454. media_header->extension = get_bit16(packet[pos],3);
  455. media_header->csrc_count = (packet[pos] >> 4) & 0x0F;
  456. pos++;
  457. media_header->marker = get_bit16(packet[pos],0);
  458. media_header->payload_type = (packet[pos] >> 1) & 0x7F;
  459. pos++;
  460. media_header->sequence_number = big_endian_read_16(packet, pos);
  461. pos+=2;
  462. media_header->timestamp = big_endian_read_32(packet, pos);
  463. pos+=4;
  464. media_header->synchronization_source = big_endian_read_32(packet, pos);
  465. pos+=4;
  466. *offset = pos;
  467. return 1;
  468. }
  469. static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t configuration){
  470. printf(" - num_channels: %d\n", configuration.num_channels);
  471. printf(" - sampling_frequency: %d\n", configuration.sampling_frequency);
  472. printf(" - channel_mode: %d\n", configuration.channel_mode);
  473. printf(" - block_length: %d\n", configuration.block_length);
  474. printf(" - subbands: %d\n", configuration.subbands);
  475. printf(" - allocation_method: %d\n", configuration.allocation_method);
  476. printf(" - bitpool_value [%d, %d] \n", configuration.min_bitpool_value, configuration.max_bitpool_value);
  477. printf("\n");
  478. }
  479. static void avrcp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
  480. UNUSED(channel);
  481. UNUSED(size);
  482. uint16_t local_cid;
  483. uint8_t status = 0xFF;
  484. bd_addr_t adress;
  485. if (packet_type != HCI_EVENT_PACKET) return;
  486. if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
  487. switch (packet[2]){
  488. case AVRCP_SUBEVENT_CONNECTION_ESTABLISHED: {
  489. local_cid = avrcp_subevent_connection_established_get_avrcp_cid(packet);
  490. status = avrcp_subevent_connection_established_get_status(packet);
  491. if (status != ERROR_CODE_SUCCESS){
  492. printf("AVRCP: Connection failed: status 0x%02x\n", status);
  493. avrcp_cid = 0;
  494. return;
  495. }
  496. avrcp_cid = local_cid;
  497. avrcp_connected = 1;
  498. avrcp_subevent_connection_established_get_bd_addr(packet, adress);
  499. printf("AVRCP: Connected to %s, cid 0x%02x\n", bd_addr_to_str(adress), avrcp_cid);
  500. // automatically enable notifications
  501. avrcp_controller_enable_notification(avrcp_cid, AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED);
  502. avrcp_controller_enable_notification(avrcp_cid, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED);
  503. avrcp_controller_enable_notification(avrcp_cid, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED);
  504. return;
  505. }
  506. case AVRCP_SUBEVENT_CONNECTION_RELEASED:
  507. printf("AVRCP: Channel released: cid 0x%02x\n", avrcp_subevent_connection_released_get_avrcp_cid(packet));
  508. avrcp_cid = 0;
  509. avrcp_connected = 0;
  510. return;
  511. default:
  512. break;
  513. }
  514. }
  515. static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
  516. UNUSED(channel);
  517. UNUSED(size);
  518. uint8_t status = 0xFF;
  519. if (packet_type != HCI_EVENT_PACKET) return;
  520. if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
  521. status = packet[5];
  522. if (!avrcp_cid) return;
  523. // ignore INTERIM status
  524. if (status == AVRCP_CTYPE_RESPONSE_INTERIM){
  525. switch (packet[2]){
  526. case AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_POS_CHANGED:{
  527. uint32_t playback_position_ms = avrcp_subevent_notification_playback_pos_changed_get_playback_position_ms(packet);
  528. if (playback_position_ms == AVRCP_NO_TRACK_SELECTED_PLAYBACK_POSITION_CHANGED){
  529. printf("AVRCP Controller: playback position changed, no track is selected\n");
  530. }
  531. break;
  532. }
  533. default:
  534. break;
  535. }
  536. return;
  537. }
  538. memset(avrcp_subevent_value, 0, sizeof(avrcp_subevent_value));
  539. switch (packet[2]){
  540. case AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_POS_CHANGED:
  541. printf("AVRCP Controller: Playback position changed, position %d ms\n", (unsigned int) avrcp_subevent_notification_playback_pos_changed_get_playback_position_ms(packet));
  542. break;
  543. case AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED:
  544. printf("AVRCP Controller: Playback status changed %s\n", avrcp_play_status2str(avrcp_subevent_notification_playback_status_changed_get_play_status(packet)));
  545. return;
  546. case AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED:
  547. printf("AVRCP Controller: Playing content changed\n");
  548. return;
  549. case AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED:
  550. printf("AVRCP Controller: Track changed\n");
  551. return;
  552. case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:
  553. printf("AVRCP Controller: Absolute volume changed %d\n", avrcp_subevent_notification_volume_changed_get_absolute_volume(packet));
  554. return;
  555. case AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED:
  556. printf("AVRCP Controller: Changed\n");
  557. return;
  558. case AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE:{
  559. uint8_t shuffle_mode = avrcp_subevent_shuffle_and_repeat_mode_get_shuffle_mode(packet);
  560. uint8_t repeat_mode = avrcp_subevent_shuffle_and_repeat_mode_get_repeat_mode(packet);
  561. printf("AVRCP Controller: %s, %s\n", avrcp_shuffle2str(shuffle_mode), avrcp_repeat2str(repeat_mode));
  562. break;
  563. }
  564. case AVRCP_SUBEVENT_NOW_PLAYING_TRACK_INFO:
  565. printf("AVRCP Controller: Track: %d\n", avrcp_subevent_now_playing_track_info_get_track(packet));
  566. break;
  567. case AVRCP_SUBEVENT_NOW_PLAYING_TOTAL_TRACKS_INFO:
  568. printf("AVRCP Controller: Total Tracks: %d\n", avrcp_subevent_now_playing_total_tracks_info_get_total_tracks(packet));
  569. break;
  570. case AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO:
  571. if (avrcp_subevent_now_playing_title_info_get_value_len(packet) > 0){
  572. memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_title_info_get_value(packet), avrcp_subevent_now_playing_title_info_get_value_len(packet));
  573. printf("AVRCP Controller: Title: %s\n", avrcp_subevent_value);
  574. }
  575. break;
  576. case AVRCP_SUBEVENT_NOW_PLAYING_ARTIST_INFO:
  577. if (avrcp_subevent_now_playing_artist_info_get_value_len(packet) > 0){
  578. memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_artist_info_get_value(packet), avrcp_subevent_now_playing_artist_info_get_value_len(packet));
  579. printf("AVRCP Controller: Artist: %s\n", avrcp_subevent_value);
  580. }
  581. break;
  582. case AVRCP_SUBEVENT_NOW_PLAYING_ALBUM_INFO:
  583. if (avrcp_subevent_now_playing_album_info_get_value_len(packet) > 0){
  584. memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_album_info_get_value(packet), avrcp_subevent_now_playing_album_info_get_value_len(packet));
  585. printf("AVRCP Controller: Album: %s\n", avrcp_subevent_value);
  586. }
  587. break;
  588. case AVRCP_SUBEVENT_NOW_PLAYING_GENRE_INFO:
  589. if (avrcp_subevent_now_playing_genre_info_get_value_len(packet) > 0){
  590. memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_genre_info_get_value(packet), avrcp_subevent_now_playing_genre_info_get_value_len(packet));
  591. printf("AVRCP Controller: Genre: %s\n", avrcp_subevent_value);
  592. }
  593. break;
  594. case AVRCP_SUBEVENT_PLAY_STATUS:
  595. printf("AVRCP Controller: Song length %"PRIu32" ms, Song position %"PRIu32" ms, Play status %s\n",
  596. avrcp_subevent_play_status_get_song_length(packet),
  597. avrcp_subevent_play_status_get_song_position(packet),
  598. avrcp_play_status2str(avrcp_subevent_play_status_get_play_status(packet)));
  599. break;
  600. case AVRCP_SUBEVENT_OPERATION_COMPLETE:
  601. printf("AVRCP Controller: %s done\n", avrcp_operation2str(avrcp_subevent_operation_complete_get_operation_id(packet)));
  602. break;
  603. case AVRCP_SUBEVENT_OPERATION_START:
  604. printf("AVRCP Controller: Start %s\n", avrcp_operation2str(avrcp_subevent_operation_complete_get_operation_id(packet)));
  605. break;
  606. default:
  607. printf("AVRCP Controller: Event 0x%02x is not parsed\n", packet[2]);
  608. break;
  609. }
  610. }
  611. static void avrcp_volume_changed(uint8_t volume){
  612. const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
  613. if (audio){
  614. audio->set_volume(volume);
  615. }
  616. }
  617. static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
  618. UNUSED(channel);
  619. UNUSED(size);
  620. if (packet_type != HCI_EVENT_PACKET) return;
  621. if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
  622. uint8_t volume;
  623. switch (packet[2]){
  624. case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:
  625. volume = avrcp_subevent_notification_volume_changed_get_absolute_volume(packet);
  626. volume_percentage = volume * 100 / 127;
  627. printf("AVRCP Target : Volume set to %d%% (%d)\n", volume_percentage, volume);
  628. avrcp_volume_changed(volume);
  629. break;
  630. case AVRCP_SUBEVENT_EVENT_IDS_QUERY:
  631. #ifdef SUPPORT_VOLUME_CHANGE_NOTIFICATION
  632. avrcp_target_supported_events(avrcp_cid, events_num, events, sizeof(events));
  633. #else
  634. avrcp_target_supported_events(avrcp_cid, 0, NULL, 0);
  635. #endif
  636. break;
  637. case AVRCP_SUBEVENT_COMPANY_IDS_QUERY:
  638. avrcp_target_supported_companies(avrcp_cid, companies_num, companies, sizeof(companies));
  639. break;
  640. case AVRCP_SUBEVENT_OPERATION:{
  641. avrcp_operation_id_t operation_id = avrcp_subevent_operation_get_operation_id(packet);
  642. switch (operation_id){
  643. case AVRCP_OPERATION_ID_PLAY:
  644. printf("AVRCP Target : PLAY\n");
  645. break;
  646. case AVRCP_OPERATION_ID_PAUSE:
  647. printf("AVRCP Target : PAUSE\n");
  648. break;
  649. case AVRCP_OPERATION_ID_STOP:
  650. printf("AVRCP Target : STOP\n");
  651. break;
  652. case AVRCP_OPERATION_ID_REWIND:
  653. printf("AVRCP Target : REWIND\n");
  654. break;
  655. case AVRCP_OPERATION_ID_FAST_FORWARD:
  656. printf("AVRCP Target : FAST_FORWARD\n");
  657. break;
  658. case AVRCP_OPERATION_ID_FORWARD:
  659. printf("AVRCP Target : FORWARD\n");
  660. break;
  661. case AVRCP_OPERATION_ID_BACKWARD:
  662. printf("AVRCP Target : BACKWARD\n");
  663. break;
  664. case AVRCP_OPERATION_ID_SKIP:
  665. printf("AVRCP Target : SKIP\n");
  666. break;
  667. case AVRCP_OPERATION_ID_MUTE:
  668. printf("AVRCP Target : MUTE\n");
  669. break;
  670. case AVRCP_OPERATION_ID_CHANNEL_UP:
  671. printf("AVRCP Target : CHANNEL_UP\n");
  672. break;
  673. case AVRCP_OPERATION_ID_CHANNEL_DOWN:
  674. printf("AVRCP Target : CHANNEL_DOWN\n");
  675. break;
  676. case AVRCP_OPERATION_ID_SELECT:
  677. printf("AVRCP Target : SELECT\n");
  678. break;
  679. case AVRCP_OPERATION_ID_UP:
  680. printf("AVRCP Target : UP\n");
  681. break;
  682. case AVRCP_OPERATION_ID_DOWN:
  683. printf("AVRCP Target : DOWN\n");
  684. break;
  685. case AVRCP_OPERATION_ID_LEFT:
  686. printf("AVRCP Target : LEFT\n");
  687. break;
  688. case AVRCP_OPERATION_ID_RIGHT:
  689. printf("AVRCP Target : RIGTH\n");
  690. break;
  691. case AVRCP_OPERATION_ID_ROOT_MENU:
  692. printf("AVRCP Target : ROOT_MENU\n");
  693. break;
  694. default:
  695. return;
  696. }
  697. break;
  698. }
  699. default:
  700. printf("AVRCP Target : Event 0x%02x is not parsed\n", packet[2]);
  701. break;
  702. }
  703. }
  704. static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
  705. UNUSED(channel);
  706. UNUSED(size);
  707. if (packet_type != HCI_EVENT_PACKET) return;
  708. if (hci_event_packet_get_type(packet) == HCI_EVENT_PIN_CODE_REQUEST) {
  709. bd_addr_t address;
  710. printf("Pin code request - using '0000'\n");
  711. hci_event_pin_code_request_get_bd_addr(packet, address);
  712. gap_pin_code_response(address, "0000");
  713. }
  714. }
  715. static void a2dp_sink_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
  716. UNUSED(channel);
  717. UNUSED(size);
  718. bd_addr_t address;
  719. uint8_t status;
  720. if (packet_type != HCI_EVENT_PACKET) return;
  721. if (hci_event_packet_get_type(packet) != HCI_EVENT_A2DP_META) return;
  722. switch (packet[2]){
  723. case A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION:
  724. printf("A2DP Sink : Received non SBC codec - not implemented\n");
  725. break;
  726. case A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
  727. printf("A2DP Sink : Received SBC codec configuration\n");
  728. sbc_configuration.reconfigure = a2dp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
  729. sbc_configuration.num_channels = a2dp_subevent_signaling_media_codec_sbc_configuration_get_num_channels(packet);
  730. sbc_configuration.sampling_frequency = a2dp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
  731. sbc_configuration.channel_mode = a2dp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
  732. sbc_configuration.block_length = a2dp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
  733. sbc_configuration.subbands = a2dp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
  734. sbc_configuration.allocation_method = a2dp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
  735. sbc_configuration.min_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_min_bitpool_value(packet);
  736. sbc_configuration.max_bitpool_value = a2dp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet);
  737. sbc_configuration.frames_per_buffer = sbc_configuration.subbands * sbc_configuration.block_length;
  738. dump_sbc_configuration(sbc_configuration);
  739. if (sbc_configuration.reconfigure){
  740. media_processing_close();
  741. }
  742. // prepare media processing
  743. media_processing_init(sbc_configuration);
  744. break;
  745. }
  746. case A2DP_SUBEVENT_STREAM_ESTABLISHED:
  747. a2dp_subevent_stream_established_get_bd_addr(packet, address);
  748. status = a2dp_subevent_stream_established_get_status(packet);
  749. if (status){
  750. printf("A2DP Sink : Streaming connection failed, status 0x%02x\n", status);
  751. break;
  752. }
  753. a2dp_cid = a2dp_subevent_stream_established_get_a2dp_cid(packet);
  754. memcpy(device_addr, address, 6);
  755. printf("A2DP Sink : Streaming connection is established, address %s, cid 0x%02X, local seid %d\n", bd_addr_to_str(address), a2dp_cid, a2dp_local_seid);
  756. break;
  757. case A2DP_SUBEVENT_STREAM_STARTED:
  758. printf("A2DP Sink : Stream started\n");
  759. media_processing_start();
  760. break;
  761. case A2DP_SUBEVENT_STREAM_SUSPENDED:
  762. printf("A2DP Sink : Stream paused\n");
  763. media_processing_pause();
  764. break;
  765. case A2DP_SUBEVENT_STREAM_RELEASED:
  766. printf("A2DP Sink : Stream released\n");
  767. media_processing_close();
  768. break;
  769. case A2DP_SUBEVENT_SIGNALING_CONNECTION_RELEASED:
  770. printf("A2DP Sink : Signaling connection released\n");
  771. media_processing_close();
  772. break;
  773. default:
  774. printf("A2DP Sink : Not parsed 0x%02x\n", packet[2]);
  775. break;
  776. }
  777. }
  778. #ifdef HAVE_BTSTACK_STDIN
  779. static void show_usage(void){
  780. bd_addr_t iut_address;
  781. gap_local_bd_addr(iut_address);
  782. printf("\n--- Bluetooth AVDTP Sink/AVRCP Connection Test Console %s ---\n", bd_addr_to_str(iut_address));
  783. printf("b - AVDTP Sink create connection to addr %s\n", bd_addr_to_str(device_addr));
  784. printf("B - AVDTP Sink disconnect\n");
  785. printf("c - AVRCP create connection to addr %s\n", bd_addr_to_str(device_addr));
  786. printf("C - AVRCP disconnect\n");
  787. printf("w - delay report\n");
  788. printf("\n--- Bluetooth AVRCP Commands %s ---\n", bd_addr_to_str(iut_address));
  789. printf("O - get play status\n");
  790. printf("j - get now playing info\n");
  791. printf("k - play\n");
  792. printf("K - stop\n");
  793. printf("L - pause\n");
  794. printf("u - start fast forward\n");
  795. printf("U - stop fast forward\n");
  796. printf("n - start rewind\n");
  797. printf("N - stop rewind\n");
  798. printf("i - forward\n");
  799. printf("I - backward\n");
  800. printf("M - mute\n");
  801. printf("r - skip\n");
  802. printf("q - query repeat and shuffle mode\n");
  803. printf("v - repeat single track\n");
  804. printf("x - repeat all tracks\n");
  805. printf("X - disable repeat mode\n");
  806. printf("z - shuffle all tracks\n");
  807. printf("Z - disable shuffle mode\n");
  808. printf("a/A - register/deregister TRACK_CHANGED\n");
  809. printf("R/P - register/deregister PLAYBACK_POS_CHANGED\n");
  810. printf("\n--- Volume Control ---\n");
  811. printf("t - volume up for 10 percent\n");
  812. printf("T - volume down for 10 percent\n");
  813. printf("---\n");
  814. }
  815. #endif
  816. #ifdef HAVE_BTSTACK_STDIN
  817. static void stdin_process(char cmd){
  818. uint8_t status = ERROR_CODE_SUCCESS;
  819. uint8_t volume;
  820. switch (cmd){
  821. case 'b':
  822. status = a2dp_sink_establish_stream(device_addr, a2dp_local_seid, &a2dp_cid);
  823. printf(" - Create AVDTP connection to addr %s, and local seid %d, expected cid 0x%02x.\n", bd_addr_to_str(device_addr), a2dp_local_seid, a2dp_cid);
  824. break;
  825. case 'B':
  826. printf(" - AVDTP disconnect from addr %s.\n", bd_addr_to_str(device_addr));
  827. status = avdtp_sink_disconnect(a2dp_cid);
  828. break;
  829. case 'c':
  830. printf(" - Create AVRCP connection to addr %s.\n", bd_addr_to_str(device_addr));
  831. status = avrcp_connect(device_addr, &avrcp_cid);
  832. break;
  833. case 'C':
  834. printf(" - AVRCP disconnect from addr %s.\n", bd_addr_to_str(device_addr));
  835. status = avrcp_disconnect(avrcp_cid);
  836. break;
  837. case '\n':
  838. case '\r':
  839. break;
  840. case 'w':
  841. printf("Send delay report\n");
  842. avdtp_sink_delay_report(a2dp_cid, a2dp_local_seid, 100);
  843. break;
  844. // Volume Control
  845. case 't':
  846. volume_percentage = volume_percentage <= 90 ? volume_percentage + 10 : 100;
  847. volume = volume_percentage * 127 / 100;
  848. printf(" - volume up for 10 percent, %d%% (%d) \n", volume_percentage, volume);
  849. status = avrcp_target_volume_changed(avrcp_cid, volume);
  850. avrcp_volume_changed(volume);
  851. break;
  852. case 'T':
  853. volume_percentage = volume_percentage >= 10 ? volume_percentage - 10 : 0;
  854. volume = volume_percentage * 127 / 100;
  855. printf(" - volume down for 10 percent, %d%% (%d) \n", volume_percentage, volume);
  856. status = avrcp_target_volume_changed(avrcp_cid, volume);
  857. avrcp_volume_changed(volume);
  858. break;
  859. case 'O':
  860. printf(" - get play status\n");
  861. status = avrcp_controller_get_play_status(avrcp_cid);
  862. break;
  863. case 'j':
  864. printf(" - get now playing info\n");
  865. status = avrcp_controller_get_now_playing_info(avrcp_cid);
  866. break;
  867. case 'k':
  868. printf(" - play\n");
  869. status = avrcp_controller_play(avrcp_cid);
  870. break;
  871. case 'K':
  872. printf(" - stop\n");
  873. status = avrcp_controller_stop(avrcp_cid);
  874. break;
  875. case 'L':
  876. printf(" - pause\n");
  877. status = avrcp_controller_pause(avrcp_cid);
  878. break;
  879. case 'u':
  880. printf(" - start fast forward\n");
  881. status = avrcp_controller_press_and_hold_fast_forward(avrcp_cid);
  882. break;
  883. case 'U':
  884. printf(" - stop fast forward\n");
  885. status = avrcp_controller_release_press_and_hold_cmd(avrcp_cid);
  886. break;
  887. case 'n':
  888. printf(" - start rewind\n");
  889. status = avrcp_controller_press_and_hold_rewind(avrcp_cid);
  890. break;
  891. case 'N':
  892. printf(" - stop rewind\n");
  893. status = avrcp_controller_release_press_and_hold_cmd(avrcp_cid);
  894. break;
  895. case 'i':
  896. printf(" - forward\n");
  897. status = avrcp_controller_forward(avrcp_cid);
  898. break;
  899. case 'I':
  900. printf(" - backward\n");
  901. status = avrcp_controller_backward(avrcp_cid);
  902. break;
  903. case 'M':
  904. printf(" - mute\n");
  905. status = avrcp_controller_mute(avrcp_cid);
  906. break;
  907. case 'r':
  908. printf(" - skip\n");
  909. status = avrcp_controller_skip(avrcp_cid);
  910. break;
  911. case 'q':
  912. printf(" - query repeat and shuffle mode\n");
  913. status = avrcp_controller_query_shuffle_and_repeat_modes(avrcp_cid);
  914. break;
  915. case 'v':
  916. printf(" - repeat single track\n");
  917. status = avrcp_controller_set_repeat_mode(avrcp_cid, AVRCP_REPEAT_MODE_SINGLE_TRACK);
  918. break;
  919. case 'x':
  920. printf(" - repeat all tracks\n");
  921. status = avrcp_controller_set_repeat_mode(avrcp_cid, AVRCP_REPEAT_MODE_ALL_TRACKS);
  922. break;
  923. case 'X':
  924. printf(" - disable repeat mode\n");
  925. status = avrcp_controller_set_repeat_mode(avrcp_cid, AVRCP_REPEAT_MODE_OFF);
  926. break;
  927. case 'z':
  928. printf(" - shuffle all tracks\n");
  929. status = avrcp_controller_set_shuffle_mode(avrcp_cid, AVRCP_SHUFFLE_MODE_ALL_TRACKS);
  930. break;
  931. case 'Z':
  932. printf(" - disable shuffle mode\n");
  933. status = avrcp_controller_set_shuffle_mode(avrcp_cid, AVRCP_SHUFFLE_MODE_OFF);
  934. break;
  935. case 'a':
  936. printf("AVRCP: enable notification TRACK_CHANGED\n");
  937. avrcp_controller_enable_notification(avrcp_cid, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED);
  938. break;
  939. case 'A':
  940. printf("AVRCP: disable notification TRACK_CHANGED\n");
  941. avrcp_controller_disable_notification(avrcp_cid, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED);
  942. break;
  943. case 'R':
  944. printf("AVRCP: enable notification PLAYBACK_POS_CHANGED\n");
  945. avrcp_controller_enable_notification(avrcp_cid, AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED);
  946. break;
  947. case 'P':
  948. printf("AVRCP: disable notification PLAYBACK_POS_CHANGED\n");
  949. avrcp_controller_disable_notification(avrcp_cid, AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED);
  950. break;
  951. default:
  952. show_usage();
  953. return;
  954. }
  955. if (status != ERROR_CODE_SUCCESS){
  956. printf("Could not perform command, status 0x%2x\n", status);
  957. }
  958. }
  959. #endif
  960. int btstack_main(int argc, const char * argv[]);
  961. int btstack_main(int argc, const char * argv[]){
  962. UNUSED(argc);
  963. (void)argv;
  964. a2dp_and_avrcp_setup();
  965. #ifdef HAVE_BTSTACK_STDIN
  966. // parse human readable Bluetooth address
  967. sscanf_bd_addr(device_addr_string, device_addr);
  968. btstack_stdin_setup(stdin_process);
  969. #endif
  970. // turn on!
  971. printf("Starting BTstack ...\n");
  972. hci_power_control(HCI_POWER_ON);
  973. return 0;
  974. }
  975. /* EXAMPLE_END */