sco_demo_util.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  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__ "sco_demo_util.c"
  38. /*
  39. * sco_demo_util.c - send/receive test data via SCO, used by hfp_*_demo and hsp_*_demo
  40. */
  41. #include <stdio.h>
  42. #include "sco_demo_util.h"
  43. #include "btstack_audio.h"
  44. #include "btstack_debug.h"
  45. #include "btstack_ring_buffer.h"
  46. #include "classic/btstack_cvsd_plc.h"
  47. #include "classic/btstack_sbc.h"
  48. #include "classic/hfp.h"
  49. #include "classic/hfp_msbc.h"
  50. #ifdef HAVE_POSIX_FILE_IO
  51. #include "wav_util.h"
  52. #endif
  53. // test modes
  54. #define SCO_DEMO_MODE_SINE 0
  55. #define SCO_DEMO_MODE_ASCII 1
  56. #define SCO_DEMO_MODE_COUNTER 2
  57. #define SCO_DEMO_MODE_55 3
  58. #define SCO_DEMO_MODE_00 4
  59. #define SCO_DEMO_MODE_MICROPHONE 5
  60. // SCO demo configuration
  61. #define SCO_DEMO_MODE SCO_DEMO_MODE_MICROPHONE
  62. // number of sco packets until 'report' on console
  63. #define SCO_REPORT_PERIOD 100
  64. // #define ENABLE_SCO_STEREO_PLAYBACK
  65. #ifdef HAVE_POSIX_FILE_IO
  66. // length and name of wav file on disk
  67. #define SCO_WAV_DURATION_IN_SECONDS 15
  68. #define SCO_WAV_FILENAME "sco_input.wav"
  69. // name of sbc test files
  70. #define SCO_MSBC_OUT_FILENAME "sco_output.msbc"
  71. #define SCO_MSBC_IN_FILENAME "sco_input.msbc"
  72. #endif
  73. // pre-buffer for CVSD and mSBC - also defines latency
  74. #define SCO_CVSD_PA_PREBUFFER_MS 50
  75. #define SCO_MSBC_PA_PREBUFFER_MS 50
  76. // constants
  77. #define NUM_CHANNELS 1
  78. #define CVSD_SAMPLE_RATE 8000
  79. #define MSBC_SAMPLE_RATE 16000
  80. #define BYTES_PER_FRAME 2
  81. #define CVSD_PA_PREBUFFER_BYTES (SCO_CVSD_PA_PREBUFFER_MS * CVSD_SAMPLE_RATE/1000 * BYTES_PER_FRAME)
  82. #define MSBC_PA_PREBUFFER_BYTES (SCO_MSBC_PA_PREBUFFER_MS * MSBC_SAMPLE_RATE/1000 * BYTES_PER_FRAME)
  83. // output
  84. #if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
  85. static int audio_output_paused = 0;
  86. static uint8_t audio_output_ring_buffer_storage[2*MSBC_PA_PREBUFFER_BYTES];
  87. static btstack_ring_buffer_t audio_output_ring_buffer;
  88. #endif
  89. // input
  90. #if SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE
  91. #define USE_AUDIO_INPUT
  92. static int audio_input_paused = 0;
  93. static uint8_t audio_input_ring_buffer_storage[2*8000]; // full second input buffer
  94. static btstack_ring_buffer_t audio_input_ring_buffer;
  95. #endif
  96. static int dump_data = 1;
  97. static int count_sent = 0;
  98. static int count_received = 0;
  99. static int negotiated_codec = -1;
  100. #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
  101. static btstack_sbc_decoder_state_t decoder_state;
  102. #ifdef HAVE_POSIX_FILE_IO
  103. FILE * msbc_file_in;
  104. FILE * msbc_file_out;
  105. #endif
  106. #endif
  107. static btstack_cvsd_plc_state_t cvsd_plc_state;
  108. #define MAX_NUM_MSBC_SAMPLES (16*8)
  109. int num_samples_to_write;
  110. int num_audio_frames;
  111. unsigned int phase;
  112. #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE
  113. // input signal: pre-computed sine wave, 266 Hz at 16000 kHz
  114. static const int16_t sine_int16_at_16000hz[] = {
  115. 0, 3135, 6237, 9270, 12202, 14999, 17633, 20073, 22294, 24270,
  116. 25980, 27406, 28531, 29344, 29835, 30000, 29835, 29344, 28531, 27406,
  117. 25980, 24270, 22294, 20073, 17633, 14999, 12202, 9270, 6237, 3135,
  118. 0, -3135, -6237, -9270, -12202, -14999, -17633, -20073, -22294, -24270,
  119. -25980, -27406, -28531, -29344, -29835, -30000, -29835, -29344, -28531, -27406,
  120. -25980, -24270, -22294, -20073, -17633, -14999, -12202, -9270, -6237, -3135,
  121. };
  122. // 8 kHz samples for CVSD/SCO packets in little endian
  123. static void sco_demo_sine_wave_int16_at_8000_hz_little_endian(unsigned int num_samples, uint8_t * data){
  124. unsigned int i;
  125. for (i=0; i < num_samples; i++){
  126. int16_t sample = sine_int16_at_16000hz[phase];
  127. little_endian_store_16(data, i * 2, sample);
  128. // ony use every second sample from 16khz table to get 8khz
  129. phase += 2;
  130. if (phase >= (sizeof(sine_int16_at_16000hz) / sizeof(int16_t))){
  131. phase = 0;
  132. }
  133. }
  134. }
  135. // 16 kHz samples for mSBC encoder in host endianess
  136. #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
  137. static void sco_demo_sine_wave_int16_at_16000_hz_host_endian(unsigned int num_samples, int16_t * data){
  138. unsigned int i;
  139. for (i=0; i < num_samples; i++){
  140. data[i] = sine_int16_at_16000hz[phase++];
  141. if (phase >= (sizeof(sine_int16_at_16000hz) / sizeof(int16_t))){
  142. phase = 0;
  143. }
  144. }
  145. }
  146. static void sco_demo_msbc_fill_sine_audio_frame(void){
  147. if (!hfp_msbc_can_encode_audio_frame_now()) return;
  148. int num_samples = hfp_msbc_num_audio_samples_per_frame();
  149. if (num_samples > MAX_NUM_MSBC_SAMPLES) return;
  150. int16_t sample_buffer[MAX_NUM_MSBC_SAMPLES];
  151. sco_demo_sine_wave_int16_at_16000_hz_host_endian(num_samples, sample_buffer);
  152. hfp_msbc_encode_audio_frame(sample_buffer);
  153. num_audio_frames++;
  154. }
  155. #endif
  156. #endif
  157. #if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
  158. static void playback_callback(int16_t * buffer, uint16_t num_samples){
  159. uint32_t prebuffer_bytes;
  160. switch (negotiated_codec){
  161. case HFP_CODEC_MSBC:
  162. prebuffer_bytes = MSBC_PA_PREBUFFER_BYTES;
  163. break;
  164. case HFP_CODEC_CVSD:
  165. default:
  166. prebuffer_bytes = CVSD_PA_PREBUFFER_BYTES;
  167. break;
  168. }
  169. // fill with silence while paused
  170. if (audio_output_paused){
  171. if (btstack_ring_buffer_bytes_available(&audio_output_ring_buffer) < prebuffer_bytes){
  172. #ifdef ENABLE_SCO_STEREO_PLAYBACK
  173. memset(buffer, 0, num_samples * BYTES_PER_FRAME * 2);
  174. #else
  175. memset(buffer, 0, num_samples * BYTES_PER_FRAME);
  176. #endif
  177. return;
  178. } else {
  179. // resume playback
  180. audio_output_paused = 0;
  181. }
  182. }
  183. // get data from ringbuffer
  184. uint32_t bytes_read = 0;
  185. #ifdef ENABLE_SCO_STEREO_PLAYBACK
  186. while (num_samples){
  187. int16_t temp[16];
  188. unsigned int bytes_to_read = btstack_min(num_samples * BYTES_PER_FRAME, sizeof(temp));
  189. btstack_ring_buffer_read(&audio_output_ring_buffer, (uint8_t *) &temp[0], bytes_to_read, &bytes_read);
  190. if (bytes_read == 0) break;
  191. unsigned int i;
  192. for (i=0;i<bytes_read / BYTES_PER_FRAME;i++){
  193. *buffer++ = temp[i];
  194. *buffer++ = temp[i];
  195. num_samples--;
  196. }
  197. }
  198. #else
  199. btstack_ring_buffer_read(&audio_output_ring_buffer, (uint8_t *) buffer, num_samples * BYTES_PER_FRAME, &bytes_read);
  200. num_samples -= bytes_read / BYTES_PER_FRAME;
  201. buffer += bytes_read / BYTES_PER_FRAME;
  202. #endif
  203. // fill with 0 if not enough
  204. if (num_samples){
  205. #ifdef ENABLE_SCO_STEREO_PLAYBACK
  206. memset(buffer, 0, num_samples * BYTES_PER_FRAME * 2);
  207. #else
  208. memset(buffer, 0, num_samples * BYTES_PER_FRAME);
  209. #endif
  210. audio_output_paused = 1;
  211. }
  212. }
  213. #ifdef USE_AUDIO_INPUT
  214. static void recording_callback(const int16_t * buffer, uint16_t num_samples){
  215. btstack_ring_buffer_write(&audio_input_ring_buffer, (uint8_t *)buffer, num_samples * 2);
  216. }
  217. #endif
  218. // return 1 if ok
  219. static int audio_initialize(int sample_rate){
  220. // -- output -- //
  221. // init buffers
  222. memset(audio_output_ring_buffer_storage, 0, sizeof(audio_output_ring_buffer_storage));
  223. btstack_ring_buffer_init(&audio_output_ring_buffer, audio_output_ring_buffer_storage, sizeof(audio_output_ring_buffer_storage));
  224. // config and setup audio playback
  225. const btstack_audio_sink_t * audio_sink = btstack_audio_sink_get_instance();
  226. if (!audio_sink) return 0;
  227. #ifdef ENABLE_SCO_STEREO_PLAYBACK
  228. audio_sink->init(2, sample_rate, &playback_callback);
  229. #else
  230. audio_sink->init(1, sample_rate, &playback_callback);
  231. #endif
  232. audio_sink->start_stream();
  233. audio_output_paused = 1;
  234. // -- input -- //
  235. #ifdef USE_AUDIO_INPUT
  236. // init buffers
  237. memset(audio_input_ring_buffer_storage, 0, sizeof(audio_input_ring_buffer_storage));
  238. btstack_ring_buffer_init(&audio_input_ring_buffer, audio_input_ring_buffer_storage, sizeof(audio_input_ring_buffer_storage));
  239. // config and setup audio recording
  240. const btstack_audio_source_t * audio_source = btstack_audio_source_get_instance();
  241. if (!audio_source) return 0;
  242. audio_source->init(1, sample_rate, &recording_callback);
  243. audio_source->start_stream();
  244. audio_input_paused = 1;
  245. #endif
  246. return 1;
  247. }
  248. static void audio_terminate(void){
  249. const btstack_audio_sink_t * audio_sink = btstack_audio_sink_get_instance();
  250. if (!audio_sink) return;
  251. audio_sink->close();
  252. #ifdef USE_AUDIO_INPUT
  253. const btstack_audio_source_t * audio_source= btstack_audio_source_get_instance();
  254. if (!audio_source) return;
  255. audio_source->close();
  256. #endif
  257. }
  258. #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
  259. static void handle_pcm_data(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context){
  260. UNUSED(context);
  261. UNUSED(sample_rate);
  262. UNUSED(data);
  263. UNUSED(num_samples);
  264. UNUSED(num_channels);
  265. #if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
  266. // printf("handle_pcm_data num samples %u, sample rate %d\n", num_samples, num_channels);
  267. // samples in callback in host endianess, ready for playback
  268. btstack_ring_buffer_write(&audio_output_ring_buffer, (uint8_t *)data, num_samples*num_channels*2);
  269. #ifdef SCO_WAV_FILENAME
  270. if (!num_samples_to_write) return;
  271. num_samples = btstack_min(num_samples, num_samples_to_write);
  272. num_samples_to_write -= num_samples;
  273. wav_writer_write_int16(num_samples, data);
  274. if (num_samples_to_write == 0){
  275. wav_writer_close();
  276. }
  277. #endif /* SCO_WAV_FILENAME */
  278. #endif /* Demo mode sine or microphone */
  279. }
  280. #endif /* ENABLE_HFP_WIDE_BAND_SPEECH */
  281. #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
  282. static void sco_demo_init_mSBC(void){
  283. printf("SCO Demo: Init mSBC\n");
  284. btstack_sbc_decoder_init(&decoder_state, SBC_MODE_mSBC, &handle_pcm_data, NULL);
  285. hfp_msbc_init();
  286. #ifdef SCO_WAV_FILENAME
  287. num_samples_to_write = MSBC_SAMPLE_RATE * SCO_WAV_DURATION_IN_SECONDS;
  288. wav_writer_open(SCO_WAV_FILENAME, 1, MSBC_SAMPLE_RATE);
  289. #endif
  290. #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE
  291. sco_demo_msbc_fill_sine_audio_frame();
  292. #endif
  293. #ifdef SCO_MSBC_IN_FILENAME
  294. msbc_file_in = fopen(SCO_MSBC_IN_FILENAME, "wb");
  295. printf("SCO Demo: creating mSBC in file %s, %p\n", SCO_MSBC_IN_FILENAME, msbc_file_in);
  296. #endif
  297. #ifdef SCO_MSBC_OUT_FILENAME
  298. msbc_file_out = fopen(SCO_MSBC_OUT_FILENAME, "wb");
  299. printf("SCO Demo: creating mSBC out file %s, %p\n", SCO_MSBC_OUT_FILENAME, msbc_file_out);
  300. #endif
  301. audio_initialize(MSBC_SAMPLE_RATE);
  302. }
  303. static void sco_demo_receive_mSBC(uint8_t * packet, uint16_t size){
  304. #ifdef HAVE_POSIX_FILE_IO
  305. if (num_samples_to_write){
  306. if (msbc_file_in){
  307. // log incoming mSBC data for testing
  308. fwrite(packet+3, size-3, 1, msbc_file_in);
  309. }
  310. }
  311. #endif
  312. btstack_sbc_decoder_process_data(&decoder_state, (packet[1] >> 4) & 3, packet+3, size-3);
  313. }
  314. #endif
  315. static void sco_demo_init_CVSD(void){
  316. printf("SCO Demo: Init CVSD\n");
  317. btstack_cvsd_plc_init(&cvsd_plc_state);
  318. #ifdef SCO_WAV_FILENAME
  319. num_samples_to_write = CVSD_SAMPLE_RATE * SCO_WAV_DURATION_IN_SECONDS;
  320. wav_writer_open(SCO_WAV_FILENAME, 1, CVSD_SAMPLE_RATE);
  321. #endif
  322. audio_initialize(CVSD_SAMPLE_RATE);
  323. }
  324. static void sco_demo_receive_CVSD(uint8_t * packet, uint16_t size){
  325. int16_t audio_frame_out[128]; //
  326. if (size > sizeof(audio_frame_out)){
  327. printf("sco_demo_receive_CVSD: SCO packet larger than local output buffer - dropping data.\n");
  328. return;
  329. }
  330. const int audio_bytes_read = size - 3;
  331. const int num_samples = audio_bytes_read / BYTES_PER_FRAME;
  332. // convert into host endian
  333. int16_t audio_frame_in[128];
  334. int i;
  335. for (i=0;i<num_samples;i++){
  336. audio_frame_in[i] = little_endian_read_16(packet, 3 + i * 2);
  337. }
  338. // treat packet as bad frame if controller does not report 'all good'
  339. bool bad_frame = (packet[1] & 0x30) != 0;
  340. btstack_cvsd_plc_process_data(&cvsd_plc_state, bad_frame, audio_frame_in, num_samples, audio_frame_out);
  341. #ifdef SCO_WAV_FILENAME
  342. // Samples in CVSD SCO packet are in little endian, ready for wav files (take shortcut)
  343. const int samples_to_write = btstack_min(num_samples, num_samples_to_write);
  344. wav_writer_write_le_int16(samples_to_write, audio_frame_out);
  345. num_samples_to_write -= samples_to_write;
  346. if (num_samples_to_write == 0){
  347. wav_writer_close();
  348. }
  349. #endif
  350. btstack_ring_buffer_write(&audio_output_ring_buffer, (uint8_t *)audio_frame_out, audio_bytes_read);
  351. }
  352. #endif
  353. void sco_demo_close(void){
  354. printf("SCO demo close\n");
  355. printf("SCO demo statistics: ");
  356. #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
  357. if (negotiated_codec == HFP_CODEC_MSBC){
  358. printf("Used mSBC with PLC, number of processed frames: \n - %d good frames, \n - %d zero frames, \n - %d bad frames.\n", decoder_state.good_frames_nr, decoder_state.zero_frames_nr, decoder_state.bad_frames_nr);
  359. } else
  360. #endif
  361. {
  362. printf("Used CVSD with PLC, number of proccesed frames: \n - %d good frames, \n - %d bad frames.\n", cvsd_plc_state.good_frames_nr, cvsd_plc_state.bad_frames_nr);
  363. }
  364. negotiated_codec = -1;
  365. #if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
  366. #if defined(SCO_WAV_FILENAME)
  367. wav_writer_close();
  368. #endif
  369. audio_terminate();
  370. #endif
  371. }
  372. void sco_demo_set_codec(uint8_t codec){
  373. if (negotiated_codec == codec) return;
  374. negotiated_codec = codec;
  375. #if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
  376. if (negotiated_codec == HFP_CODEC_MSBC){
  377. #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
  378. sco_demo_init_mSBC();
  379. #endif
  380. } else {
  381. sco_demo_init_CVSD();
  382. }
  383. #endif
  384. }
  385. void sco_demo_init(void){
  386. // status
  387. #if SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE
  388. printf("SCO Demo: Sending and receiving audio via btstack_audio.\n");
  389. #endif
  390. #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE
  391. if (btstack_audio_sink_get_instance()){
  392. printf("SCO Demo: Sending sine wave, audio output via btstack_audio.\n");
  393. } else {
  394. printf("SCO Demo: Sending sine wave, hexdump received data.\n");
  395. }
  396. #endif
  397. #if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII
  398. printf("SCO Demo: Sending ASCII blocks, print received data.\n");
  399. #endif
  400. #if SCO_DEMO_MODE == SCO_DEMO_MODE_COUNTER
  401. printf("SCO Demo: Sending counter value, hexdump received data.\n");
  402. #endif
  403. #if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
  404. hci_set_sco_voice_setting(0x60); // linear, unsigned, 16-bit, CVSD
  405. #else
  406. hci_set_sco_voice_setting(0x03); // linear, unsigned, 8-bit, transparent
  407. #endif
  408. }
  409. void sco_report(void);
  410. void sco_report(void){
  411. printf("SCO: sent %u, received %u\n", count_sent, count_received);
  412. }
  413. void sco_demo_send(hci_con_handle_t sco_handle){
  414. if (sco_handle == HCI_CON_HANDLE_INVALID) return;
  415. int sco_packet_length = hci_get_sco_packet_length();
  416. int sco_payload_length = sco_packet_length - 3;
  417. hci_reserve_packet_buffer();
  418. uint8_t * sco_packet = hci_get_outgoing_packet_buffer();
  419. #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE
  420. #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
  421. if (negotiated_codec == HFP_CODEC_MSBC){
  422. if (hfp_msbc_num_bytes_in_stream() < sco_payload_length){
  423. log_error("mSBC stream is empty.");
  424. }
  425. hfp_msbc_read_from_stream(sco_packet + 3, sco_payload_length);
  426. #ifdef HAVE_POSIX_FILE_IO
  427. if (msbc_file_out){
  428. // log outgoing mSBC data for testing
  429. fwrite(sco_packet + 3, sco_payload_length, 1, msbc_file_out);
  430. }
  431. #endif
  432. sco_demo_msbc_fill_sine_audio_frame();
  433. } else
  434. #endif
  435. {
  436. const int audio_samples_per_packet = sco_payload_length / BYTES_PER_FRAME;
  437. sco_demo_sine_wave_int16_at_8000_hz_little_endian(audio_samples_per_packet, &sco_packet[3]);
  438. }
  439. #endif
  440. #if SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE
  441. if (btstack_audio_source_get_instance()){
  442. if (negotiated_codec == HFP_CODEC_MSBC){
  443. // MSBC
  444. if (audio_input_paused){
  445. if (btstack_ring_buffer_bytes_available(&audio_input_ring_buffer) >= MSBC_PA_PREBUFFER_BYTES){
  446. // resume sending
  447. audio_input_paused = 0;
  448. }
  449. }
  450. if (!audio_input_paused){
  451. int num_samples = hfp_msbc_num_audio_samples_per_frame();
  452. if (num_samples > MAX_NUM_MSBC_SAMPLES) return; // assert
  453. if (hfp_msbc_can_encode_audio_frame_now() && btstack_ring_buffer_bytes_available(&audio_input_ring_buffer) >= (unsigned int)(num_samples * BYTES_PER_FRAME)){
  454. int16_t sample_buffer[MAX_NUM_MSBC_SAMPLES];
  455. uint32_t bytes_read;
  456. btstack_ring_buffer_read(&audio_input_ring_buffer, (uint8_t*) sample_buffer, num_samples * BYTES_PER_FRAME, &bytes_read);
  457. hfp_msbc_encode_audio_frame(sample_buffer);
  458. num_audio_frames++;
  459. }
  460. if (hfp_msbc_num_bytes_in_stream() < sco_payload_length){
  461. log_error("mSBC stream should not be empty.");
  462. }
  463. }
  464. if (audio_input_paused || hfp_msbc_num_bytes_in_stream() < sco_payload_length){
  465. memset(sco_packet + 3, 0, sco_payload_length);
  466. audio_input_paused = 1;
  467. } else {
  468. hfp_msbc_read_from_stream(sco_packet + 3, sco_payload_length);
  469. #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
  470. #ifdef HAVE_POSIX_FILE_IO
  471. if (msbc_file_out){
  472. // log outgoing mSBC data for testing
  473. fwrite(sco_packet + 3, sco_payload_length, 1, msbc_file_out);
  474. }
  475. #endif
  476. #endif
  477. }
  478. } else {
  479. // CVSD
  480. log_debug("send: bytes avail %u, free %u", btstack_ring_buffer_bytes_available(&audio_input_ring_buffer), btstack_ring_buffer_bytes_free(&audio_input_ring_buffer));
  481. // fill with silence while paused
  482. int bytes_to_copy = sco_payload_length;
  483. if (audio_input_paused){
  484. if (btstack_ring_buffer_bytes_available(&audio_input_ring_buffer) >= CVSD_PA_PREBUFFER_BYTES){
  485. // resume sending
  486. audio_input_paused = 0;
  487. }
  488. }
  489. // get data from ringbuffer
  490. uint16_t pos = 0;
  491. uint8_t * sample_data = &sco_packet[3];
  492. if (!audio_input_paused){
  493. uint32_t bytes_read = 0;
  494. btstack_ring_buffer_read(&audio_input_ring_buffer, sample_data, bytes_to_copy, &bytes_read);
  495. // flip 16 on big endian systems
  496. // @note We don't use (uint16_t *) casts since all sample addresses are odd which causes crahses on some systems
  497. if (btstack_is_big_endian()){
  498. unsigned int i;
  499. for (i=0;i<bytes_read;i+=2){
  500. uint8_t tmp = sample_data[i*2];
  501. sample_data[i*2] = sample_data[i*2+1];
  502. sample_data[i*2+1] = tmp;
  503. }
  504. }
  505. bytes_to_copy -= bytes_read;
  506. pos += bytes_read;
  507. }
  508. // fill with 0 if not enough
  509. if (bytes_to_copy){
  510. memset(sample_data + pos, 0, bytes_to_copy);
  511. audio_input_paused = 1;
  512. }
  513. }
  514. }
  515. else {
  516. // just send '0's
  517. memset(sco_packet + 3, 0, sco_payload_length);
  518. }
  519. #endif
  520. #if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII
  521. // store packet counter-xxxx
  522. snprintf((char *)&sco_packet[3], 5, "%04u", phase++);
  523. uint8_t ascii = (phase & 0x0f) + 'a';
  524. sco_packet[3+4] = '-';
  525. memset(&sco_packet[3+5], ascii, sco_payload_length-5);
  526. #endif
  527. #if SCO_DEMO_MODE == SCO_DEMO_MODE_COUNTER
  528. int j;
  529. for (j=0;j<sco_payload_length;j++){
  530. sco_packet[3+j] = phase++;
  531. }
  532. #endif
  533. #if SCO_DEMO_MODE == SCO_DEMO_MODE_55
  534. int j;
  535. for (j=0;j<sco_payload_length;j++){
  536. // sco_packet[3+j] = j & 1 ? 0x35 : 0x53;
  537. sco_packet[3+j] = 0x55;
  538. }
  539. #endif
  540. #if SCO_DEMO_MODE == SCO_DEMO_MODE_00
  541. int j;
  542. for (j=0;j<sco_payload_length;j++){
  543. sco_packet[3+j] = 0x00;
  544. }
  545. // additional hack
  546. // big_endian_store_16(sco_packet, 5, phase++);
  547. (void) phase;
  548. #endif
  549. // test silence
  550. // memset(sco_packet+3, 0, sco_payload_length);
  551. // set handle + flags
  552. little_endian_store_16(sco_packet, 0, sco_handle);
  553. // set len
  554. sco_packet[2] = sco_payload_length;
  555. // finally send packet
  556. hci_send_sco_packet_buffer(sco_packet_length);
  557. // request another send event
  558. hci_request_sco_can_send_now_event();
  559. count_sent++;
  560. #if SCO_DEMO_MODE != SCO_DEMO_MODE_55
  561. if ((count_sent % SCO_REPORT_PERIOD) == 0) sco_report();
  562. #endif
  563. }
  564. /**
  565. * @brief Process received data
  566. */
  567. #define ANSI_COLOR_RED "\x1b[31m"
  568. #define ANSI_COLOR_GREEN "\x1b[32m"
  569. #define ANSI_COLOR_YELLOW "\x1b[33m"
  570. #define ANSI_COLOR_BLUE "\x1b[34m"
  571. #define ANSI_COLOR_MAGENTA "\x1b[35m"
  572. #define ANSI_COLOR_CYAN "\x1b[36m"
  573. #define ANSI_COLOR_RESET "\x1b[0m"
  574. void sco_demo_receive(uint8_t * packet, uint16_t size){
  575. dump_data = 1;
  576. count_received++;
  577. static uint32_t packets = 0;
  578. static uint32_t crc_errors = 0;
  579. static uint32_t data_received = 0;
  580. static uint32_t byte_errors = 0;
  581. data_received += size - 3;
  582. packets++;
  583. if (data_received > 100000){
  584. printf("Summary: data %07u, packets %04u, packet with crc errors %0u, byte errors %04u\n", (unsigned int) data_received, (unsigned int) packets, (unsigned int) crc_errors, (unsigned int) byte_errors);
  585. crc_errors = 0;
  586. byte_errors = 0;
  587. data_received = 0;
  588. packets = 0;
  589. }
  590. #if (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) || (SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE)
  591. switch (negotiated_codec){
  592. #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
  593. case HFP_CODEC_MSBC:
  594. sco_demo_receive_mSBC(packet, size);
  595. break;
  596. #endif
  597. case HFP_CODEC_CVSD:
  598. sco_demo_receive_CVSD(packet, size);
  599. break;
  600. default:
  601. break;
  602. }
  603. dump_data = 0;
  604. #endif
  605. #if 0
  606. if (packet[1] & 0x30){
  607. crc_errors++;
  608. printf("SCO CRC Error: %x - data: ", (packet[1] & 0x30) >> 4);
  609. printf_hexdump(&packet[3], size-3);
  610. return;
  611. }
  612. #endif
  613. if (dump_data){
  614. #if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII
  615. printf("data: ");
  616. int i;
  617. for (i=3;i<size;i++){
  618. printf("%c", packet[i]);
  619. }
  620. printf("\n");
  621. dump_data = 0;
  622. #endif
  623. #if SCO_DEMO_MODE == SCO_DEMO_MODE_COUNTER
  624. // colored hexdump with expected
  625. static uint8_t expected_byte = 0;
  626. int i;
  627. printf("data: ");
  628. for (i=3;i<size;i++){
  629. if (packet[i] != expected_byte){
  630. printf(ANSI_COLOR_RED "%02x " ANSI_COLOR_RESET, packet[i]);
  631. } else {
  632. printf("%02x ", packet[i]);
  633. }
  634. expected_byte = packet[i]+1;
  635. }
  636. printf("\n");
  637. #endif
  638. #if SCO_DEMO_MODE == SCO_DEMO_MODE_55 || SCO_DEMO_MODE == SCO_DEMO_MODE_00
  639. int i;
  640. int contains_error = 0;
  641. for (i=3;i<size;i++){
  642. if (packet[i] != 0x00 && packet[i] != 0x35 && packet[i] != 0x53 && packet[i] != 0x55){
  643. contains_error = 1;
  644. byte_errors++;
  645. }
  646. }
  647. if (contains_error){
  648. printf("data: ");
  649. for (i=0;i<3;i++){
  650. printf("%02x ", packet[i]);
  651. }
  652. for (i=3;i<size;i++){
  653. if (packet[i] != 0x00 && packet[i] != 0x35 && packet[i] != 0x53 && packet[i] != 0x55){
  654. printf(ANSI_COLOR_RED "%02x " ANSI_COLOR_RESET, packet[i]);
  655. } else {
  656. printf("%02x ", packet[i]);
  657. }
  658. }
  659. printf("\n");
  660. }
  661. #endif
  662. }
  663. }