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 BLUEKITCHEN 24 * GMBH 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__ "sco_demo_util.c" 39 40 /* 41 * sco_demo_util.c - send/receive test data via SCO, used by hfp_*_demo and hsp_*_demo 42 */ 43 44 #include <stdio.h> 45 46 #include "sco_demo_util.h" 47 48 #include "btstack_audio.h" 49 #include "btstack_debug.h" 50 #include "btstack_ring_buffer.h" 51 #include "classic/btstack_cvsd_plc.h" 52 #include "classic/btstack_sbc.h" 53 #include "classic/hfp.h" 54 #include "classic/hfp_codec.h" 55 56 #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH 57 #include "btstack_lc3.h" 58 #include "btstack_lc3_google.h" 59 #endif 60 61 62 #ifdef _MSC_VER 63 // ignore deprecated warning for fopen 64 #pragma warning(disable : 4996) 65 #endif 66 67 #ifdef HAVE_POSIX_FILE_IO 68 #include "wav_util.h" 69 #endif 70 71 // test modes 72 #define SCO_DEMO_MODE_SINE 0 73 #define SCO_DEMO_MODE_MICROPHONE 1 74 #define SCO_DEMO_MODE_MODPLAYER 2 75 76 // SCO demo configuration 77 #define SCO_DEMO_MODE SCO_DEMO_MODE_MICROPHONE 78 79 // number of sco packets until 'report' on console 80 #define SCO_REPORT_PERIOD 100 81 82 83 #ifdef HAVE_POSIX_FILE_IO 84 // length and name of wav file on disk 85 #define SCO_WAV_DURATION_IN_SECONDS 15 86 #define SCO_WAV_FILENAME "sco_input.wav" 87 #endif 88 89 // constants 90 #define NUM_CHANNELS 1 91 #define SAMPLE_RATE_8KHZ 8000 92 #define SAMPLE_RATE_16KHZ 16000 93 #define SAMPLE_RATE_32KHZ 32000 94 #define BYTES_PER_FRAME 2 95 96 // audio pre-buffer - also defines latency 97 #define SCO_PREBUFFER_MS 50 98 #define PREBUFFER_BYTES_8KHZ (SCO_PREBUFFER_MS * SAMPLE_RATE_8KHZ/1000 * BYTES_PER_FRAME) 99 #define PREBUFFER_BYTES_16KHZ (SCO_PREBUFFER_MS * SAMPLE_RATE_16KHZ/1000 * BYTES_PER_FRAME) 100 #define PREBUFFER_BYTES_32KHZ (SCO_PREBUFFER_MS * SAMPLE_RATE_32KHZ/1000 * BYTES_PER_FRAME) 101 102 #if defined(ENABLE_HFP_SUPER_WIDE_BAND_SPEECH) 103 #define PREBUFFER_BYTES_MAX PREBUFFER_BYTES_32KHZ 104 #define SAMPLES_PER_FRAME_MAX 240 105 #elif defined(ENABLE_HFP_WIDE_BAND_SPEECH) 106 #define PREBUFFER_BYTES_MAX PREBUFFER_BYTES_16KHZ 107 #define SAMPLES_PER_FRAME_MAX 120 108 #else 109 #define PREBUFFER_BYTES_MAX PREBUFFER_BYTES_8KHZ 110 #define SAMPLES_PER_FRAME_MAX 60 111 #endif 112 113 static uint16_t audio_prebuffer_bytes; 114 115 // output 116 static int audio_output_paused = 0; 117 static uint8_t audio_output_ring_buffer_storage[2 * PREBUFFER_BYTES_MAX]; 118 static btstack_ring_buffer_t audio_output_ring_buffer; 119 120 // input 121 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE 122 #define USE_AUDIO_INPUT 123 #else 124 #define USE_ADUIO_GENERATOR 125 static void (*sco_demo_audio_generator)(uint16_t num_samples, int16_t * data); 126 #endif 127 128 static int audio_input_paused = 0; 129 static uint8_t audio_input_ring_buffer_storage[2 * PREBUFFER_BYTES_MAX]; 130 static btstack_ring_buffer_t audio_input_ring_buffer; 131 132 // mod player 133 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MODPLAYER 134 #include "hxcmod.h" 135 #include "mods/mod.h" 136 static modcontext mod_context; 137 #endif 138 139 static int count_sent = 0; 140 static int count_received = 0; 141 142 static btstack_cvsd_plc_state_t cvsd_plc_state; 143 144 #ifdef ENABLE_HFP_WIDE_BAND_SPEECH 145 static btstack_sbc_encoder_state_t msbc_encoder_state; 146 static btstack_sbc_decoder_state_t msbc_decoder_state; 147 #endif 148 149 #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH 150 static const btstack_lc3_decoder_t * lc3_decoder; 151 static btstack_lc3_decoder_google_t lc3_decoder_context; 152 static btstack_lc3_encoder_google_t lc3_encoder_context; 153 static hfp_h2_sync_t hfp_h2_sync; 154 #endif 155 156 int num_samples_to_write; 157 int num_audio_frames; 158 159 // generic codec support 160 typedef struct { 161 void (*init)(void); 162 void(*receive)(const uint8_t * packet, uint16_t size); 163 void (*fill_payload)(uint8_t * payload_buffer, uint16_t sco_payload_length); 164 void (*close)(void); 165 // 166 uint16_t sample_rate; 167 } codec_support_t; 168 169 // current configuration 170 static const codec_support_t * codec_current = NULL; 171 172 // hfp_codec 173 static hfp_codec_t hfp_codec; 174 175 // Sine Wave 176 177 #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 178 static uint16_t sine_wave_phase; 179 static uint16_t sine_wave_steps_per_sample; 180 #define SINE_WAVE_SAMPLE_RATE SAMPLE_RATE_32KHZ 181 182 // input signal: pre-computed int16 sine wave, 32000 Hz at 266 Hz 183 static const int16_t sine_int16[] = { 184 0, 1715, 3425, 5126, 6813, 8481, 10126, 11743, 13328, 14876, 185 16383, 17846, 19260, 20621, 21925, 23170, 24351, 25465, 26509, 27481, 186 28377, 29196, 29934, 30591, 31163, 31650, 32051, 32364, 32587, 32722, 187 32767, 32722, 32587, 32364, 32051, 31650, 31163, 30591, 29934, 29196, 188 28377, 27481, 26509, 25465, 24351, 23170, 21925, 20621, 19260, 17846, 189 16383, 14876, 13328, 11743, 10126, 8481, 6813, 5126, 3425, 1715, 190 0, -1715, -3425, -5126, -6813, -8481, -10126, -11743, -13328, -14876, 191 -16384, -17846, -19260, -20621, -21925, -23170, -24351, -25465, -26509, -27481, 192 -28377, -29196, -29934, -30591, -31163, -31650, -32051, -32364, -32587, -32722, 193 -32767, -32722, -32587, -32364, -32051, -31650, -31163, -30591, -29934, -29196, 194 -28377, -27481, -26509, -25465, -24351, -23170, -21925, -20621, -19260, -17846, 195 -16384, -14876, -13328, -11743, -10126, -8481, -6813, -5126, -3425, -1715, 196 }; 197 198 static void sco_demo_sine_wave_host_endian(uint16_t num_samples, int16_t * data){ 199 unsigned int i; 200 for (i=0; i < num_samples; i++){ 201 data[i] = sine_int16[sine_wave_phase]; 202 sine_wave_phase += sine_wave_steps_per_sample; 203 if (sine_wave_phase >= (sizeof(sine_int16) / sizeof(int16_t))){ 204 sine_wave_phase = 0; 205 } 206 } 207 } 208 #endif 209 210 // Mod Player 211 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MODPLAYER 212 #define NUM_SAMPLES_GENERATOR_BUFFER 30 213 static void sco_demo_modplayer(uint16_t num_samples, int16_t * data){ 214 // mix down stereo 215 signed short samples[NUM_SAMPLES_GENERATOR_BUFFER * 2]; 216 while (num_samples > 0){ 217 uint16_t next_samples = btstack_min(num_samples, NUM_SAMPLES_GENERATOR_BUFFER); 218 hxcmod_fillbuffer(&mod_context, (unsigned short *) samples, next_samples, NULL); 219 num_samples -= next_samples; 220 uint16_t i; 221 for (i=0;i<next_samples;i++){ 222 int32_t left = samples[2*i + 0]; 223 int32_t right = samples[2*i + 1]; 224 data[i] = (int16_t)((left + right) / 2); 225 } 226 } 227 } 228 #endif 229 230 // Audio Playback / Recording 231 232 static void audio_playback_callback(int16_t * buffer, uint16_t num_samples){ 233 234 // fill with silence while paused 235 if (audio_output_paused){ 236 if (btstack_ring_buffer_bytes_available(&audio_output_ring_buffer) < audio_prebuffer_bytes){ 237 memset(buffer, 0, num_samples * BYTES_PER_FRAME); 238 return; 239 } else { 240 // resume playback 241 audio_output_paused = 0; 242 } 243 } 244 245 // get data from ringbuffer 246 uint32_t bytes_read = 0; 247 btstack_ring_buffer_read(&audio_output_ring_buffer, (uint8_t *) buffer, num_samples * BYTES_PER_FRAME, &bytes_read); 248 num_samples -= bytes_read / BYTES_PER_FRAME; 249 buffer += bytes_read / BYTES_PER_FRAME; 250 251 // fill with 0 if not enough 252 if (num_samples){ 253 memset(buffer, 0, num_samples * BYTES_PER_FRAME); 254 audio_output_paused = 1; 255 } 256 } 257 258 #ifdef USE_AUDIO_INPUT 259 static void audio_recording_callback(const int16_t * buffer, uint16_t num_samples){ 260 btstack_ring_buffer_write(&audio_input_ring_buffer, (uint8_t *)buffer, num_samples * 2); 261 } 262 #endif 263 264 // return 1 if ok 265 static int audio_initialize(int sample_rate){ 266 267 // -- output -- // 268 269 // init buffers 270 memset(audio_output_ring_buffer_storage, 0, sizeof(audio_output_ring_buffer_storage)); 271 btstack_ring_buffer_init(&audio_output_ring_buffer, audio_output_ring_buffer_storage, sizeof(audio_output_ring_buffer_storage)); 272 273 // config and setup audio playback 274 const btstack_audio_sink_t * audio_sink = btstack_audio_sink_get_instance(); 275 if (audio_sink != NULL){ 276 audio_sink->init(1, sample_rate, &audio_playback_callback); 277 audio_sink->start_stream(); 278 279 audio_output_paused = 1; 280 } 281 282 // -- input -- // 283 284 // init buffers 285 memset(audio_input_ring_buffer_storage, 0, sizeof(audio_input_ring_buffer_storage)); 286 btstack_ring_buffer_init(&audio_input_ring_buffer, audio_input_ring_buffer_storage, sizeof(audio_input_ring_buffer_storage)); 287 audio_input_paused = 1; 288 289 #ifdef USE_AUDIO_INPUT 290 // config and setup audio recording 291 const btstack_audio_source_t * audio_source = btstack_audio_source_get_instance(); 292 if (audio_source != NULL){ 293 audio_source->init(1, sample_rate, &audio_recording_callback); 294 audio_source->start_stream(); 295 } 296 #endif 297 298 return 1; 299 } 300 301 static void audio_terminate(void){ 302 const btstack_audio_sink_t * audio_sink = btstack_audio_sink_get_instance(); 303 if (!audio_sink) return; 304 audio_sink->close(); 305 306 #ifdef USE_AUDIO_INPUT 307 const btstack_audio_source_t * audio_source= btstack_audio_source_get_instance(); 308 if (!audio_source) return; 309 audio_source->close(); 310 #endif 311 } 312 313 314 // CVSD - 8 kHz 315 316 static void sco_demo_cvsd_init(void){ 317 printf("SCO Demo: Init CVSD\n"); 318 btstack_cvsd_plc_init(&cvsd_plc_state); 319 } 320 321 static void sco_demo_cvsd_receive(const uint8_t * packet, uint16_t size){ 322 323 int16_t audio_frame_out[128]; // 324 325 if (size > sizeof(audio_frame_out)){ 326 printf("sco_demo_cvsd_receive: SCO packet larger than local output buffer - dropping data.\n"); 327 return; 328 } 329 330 const int audio_bytes_read = size - 3; 331 const int num_samples = audio_bytes_read / BYTES_PER_FRAME; 332 333 // convert into host endian 334 int16_t audio_frame_in[128]; 335 int i; 336 for (i=0;i<num_samples;i++){ 337 audio_frame_in[i] = little_endian_read_16(packet, 3 + i * 2); 338 } 339 340 // treat packet as bad frame if controller does not report 'all good' 341 bool bad_frame = (packet[1] & 0x30) != 0; 342 343 btstack_cvsd_plc_process_data(&cvsd_plc_state, bad_frame, audio_frame_in, num_samples, audio_frame_out); 344 345 #ifdef SCO_WAV_FILENAME 346 // Samples in CVSD SCO packet are in little endian, ready for wav files (take shortcut) 347 const int samples_to_write = btstack_min(num_samples, num_samples_to_write); 348 wav_writer_write_le_int16(samples_to_write, audio_frame_out); 349 num_samples_to_write -= samples_to_write; 350 if (num_samples_to_write == 0){ 351 wav_writer_close(); 352 } 353 #endif 354 355 btstack_ring_buffer_write(&audio_output_ring_buffer, (uint8_t *)audio_frame_out, audio_bytes_read); 356 } 357 358 static void sco_demo_cvsd_fill_payload(uint8_t * payload_buffer, uint16_t sco_payload_length){ 359 uint16_t bytes_to_copy = sco_payload_length; 360 361 // get data from ringbuffer 362 uint16_t pos = 0; 363 if (!audio_input_paused){ 364 uint16_t samples_to_copy = sco_payload_length / 2; 365 uint32_t bytes_read = 0; 366 btstack_ring_buffer_read(&audio_input_ring_buffer, payload_buffer, bytes_to_copy, &bytes_read); 367 // flip 16 on big endian systems 368 // @note We don't use (uint16_t *) casts since all sample addresses are odd which causes crahses on some systems 369 if (btstack_is_big_endian()){ 370 uint16_t i; 371 for (i=0;i<samples_to_copy/2;i+=2){ 372 uint8_t tmp = payload_buffer[i*2]; 373 payload_buffer[i*2] = payload_buffer[i*2+1]; 374 payload_buffer[i*2+1] = tmp; 375 } 376 } 377 bytes_to_copy -= bytes_read; 378 pos += bytes_read; 379 } 380 381 // fill with 0 if not enough 382 if (bytes_to_copy){ 383 memset(payload_buffer + pos, 0, bytes_to_copy); 384 audio_input_paused = 1; 385 } 386 } 387 388 static void sco_demo_cvsd_close(void){ 389 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); 390 } 391 392 static const codec_support_t codec_cvsd = { 393 .init = &sco_demo_cvsd_init, 394 .receive = &sco_demo_cvsd_receive, 395 .fill_payload = &sco_demo_cvsd_fill_payload, 396 .close = &sco_demo_cvsd_close, 397 .sample_rate = SAMPLE_RATE_8KHZ 398 }; 399 400 // encode using hfp_codec 401 #if defined(ENABLE_HFP_WIDE_BAND_SPEECH) || defined(ENABLE_HFP_SUPER_WIDE_BAND_SPEECH) 402 static void sco_demo_codec_fill_payload(uint8_t * payload_buffer, uint16_t sco_payload_length){ 403 if (!audio_input_paused){ 404 int num_samples = hfp_codec_num_audio_samples_per_frame(&hfp_codec); 405 btstack_assert(num_samples <= SAMPLES_PER_FRAME_MAX); 406 uint16_t samples_available = btstack_ring_buffer_bytes_available(&audio_input_ring_buffer) / BYTES_PER_FRAME; 407 if (hfp_codec_can_encode_audio_frame_now(&hfp_codec) && samples_available >= num_samples){ 408 int16_t sample_buffer[SAMPLES_PER_FRAME_MAX]; 409 uint32_t bytes_read; 410 btstack_ring_buffer_read(&audio_input_ring_buffer, (uint8_t*) sample_buffer, num_samples * BYTES_PER_FRAME, &bytes_read); 411 hfp_codec_encode_audio_frame(&hfp_codec, sample_buffer); 412 num_audio_frames++; 413 } 414 } 415 // get data from encoder, fill with 0 if not enough 416 if (audio_input_paused || hfp_codec_num_bytes_available(&hfp_codec) < sco_payload_length){ 417 // just send '0's 418 memset(payload_buffer, 0, sco_payload_length); 419 audio_input_paused = 1; 420 } else { 421 hfp_codec_read_from_stream(&hfp_codec, payload_buffer, sco_payload_length); 422 } 423 } 424 #endif 425 426 // mSBC - 16 kHz 427 428 #ifdef ENABLE_HFP_WIDE_BAND_SPEECH 429 430 static void handle_pcm_data(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context){ 431 UNUSED(context); 432 UNUSED(sample_rate); 433 UNUSED(data); 434 UNUSED(num_samples); 435 UNUSED(num_channels); 436 437 // samples in callback in host endianess, ready for playback 438 btstack_ring_buffer_write(&audio_output_ring_buffer, (uint8_t *)data, num_samples*num_channels*2); 439 440 #ifdef SCO_WAV_FILENAME 441 if (!num_samples_to_write) return; 442 num_samples = btstack_min(num_samples, num_samples_to_write); 443 num_samples_to_write -= num_samples; 444 wav_writer_write_int16(num_samples, data); 445 if (num_samples_to_write == 0){ 446 wav_writer_close(); 447 } 448 #endif /* SCO_WAV_FILENAME */ 449 } 450 451 static void sco_demo_msbc_init(void){ 452 printf("SCO Demo: Init mSBC\n"); 453 btstack_sbc_decoder_init(&msbc_decoder_state, SBC_MODE_mSBC, &handle_pcm_data, NULL); 454 hfp_codec_init_msbc(&hfp_codec, &msbc_encoder_state); 455 } 456 457 static void sco_demo_msbc_receive(const uint8_t * packet, uint16_t size){ 458 btstack_sbc_decoder_process_data(&msbc_decoder_state, (packet[1] >> 4) & 3, packet + 3, size - 3); 459 } 460 461 static void sco_demo_msbc_close(void){ 462 printf("Used mSBC with PLC, number of processed frames: \n - %d good frames, \n - %d zero frames, \n - %d bad frames.\n", msbc_decoder_state.good_frames_nr, msbc_decoder_state.zero_frames_nr, msbc_decoder_state.bad_frames_nr); 463 } 464 465 static const codec_support_t codec_msbc = { 466 .init = &sco_demo_msbc_init, 467 .receive = &sco_demo_msbc_receive, 468 .fill_payload = &sco_demo_codec_fill_payload, 469 .close = &sco_demo_msbc_close, 470 .sample_rate = SAMPLE_RATE_16KHZ 471 }; 472 473 #endif /* ENABLE_HFP_WIDE_BAND_SPEECH */ 474 475 #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH 476 477 #define LC3_SWB_SAMPLES_PER_FRAME 240 478 #define LC3_SWB_OCTETS_PER_FRAME 58 479 480 static bool sco_demo_lc3swb_frame_callback(bool bad_frame, const uint8_t * frame_data, uint16_t frame_len){ 481 482 // skip H2 header for good frames 483 if (bad_frame == false){ 484 btstack_assert(frame_data != NULL); 485 frame_data += 2; 486 } 487 488 uint8_t tmp_BEC_detect = 0; 489 uint8_t BFI = bad_frame ? 1 : 0; 490 int16_t samples[LC3_SWB_SAMPLES_PER_FRAME]; 491 (void) lc3_decoder->decode_signed_16(&lc3_decoder_context, frame_data, BFI, 492 samples, 1, &tmp_BEC_detect); 493 494 // samples in callback in host endianess, ready for playback 495 btstack_ring_buffer_write(&audio_output_ring_buffer, (uint8_t *)samples, LC3_SWB_SAMPLES_PER_FRAME*2); 496 497 #ifdef SCO_WAV_FILENAME 498 if (num_samples_to_write > 0){ 499 uint16_t num_samples = btstack_min(LC3_SWB_SAMPLES_PER_FRAME, num_samples_to_write); 500 num_samples_to_write -= num_samples; 501 wav_writer_write_int16(num_samples, samples); 502 if (num_samples_to_write == 0){ 503 wav_writer_close(); 504 } 505 } 506 #endif /* SCO_WAV_FILENAME */ 507 508 // frame is good, if it isn't a bad frame and we didn't detect other errors 509 return (bad_frame == false) && (tmp_BEC_detect == 0); 510 } 511 512 static void sco_demo_lc3swb_init(void){ 513 514 printf("SCO Demo: Init LC3-SWB\n"); 515 516 const btstack_lc3_encoder_t * lc3_encoder = btstack_lc3_encoder_google_init_instance((btstack_lc3_encoder_google_t *) hfp_codec.lc3_encoder_context); 517 hfp_codec_init_lc3_swb(&hfp_codec, lc3_encoder, &lc3_encoder_context); 518 519 // init lc3 decoder 520 lc3_decoder = btstack_lc3_decoder_google_init_instance(&lc3_decoder_context); 521 lc3_decoder->configure(&lc3_decoder_context, SAMPLE_RATE_32KHZ, BTSTACK_LC3_FRAME_DURATION_7500US, LC3_SWB_OCTETS_PER_FRAME); 522 523 // init HPF H2 framing 524 hfp_h2_sync_init(&hfp_h2_sync, &sco_demo_lc3swb_frame_callback); 525 } 526 527 static void sco_demo_lc3swb_receive(const uint8_t * packet, uint16_t size){ 528 uint8_t packet_status = (packet[1] >> 4) & 3; 529 bool bad_frame = packet_status != 0; 530 hfp_h2_sync_process(&hfp_h2_sync, bad_frame, &packet[3], size-3); 531 } 532 533 static void sco_demo_lc3swb_close(void){ 534 // TODO: report 535 } 536 537 static const codec_support_t codec_lc3swb = { 538 .init = &sco_demo_lc3swb_init, 539 .receive = &sco_demo_lc3swb_receive, 540 .fill_payload = &sco_demo_codec_fill_payload, 541 .close = &sco_demo_lc3swb_close, 542 .sample_rate = SAMPLE_RATE_32KHZ 543 }; 544 #endif 545 546 void sco_demo_init(void){ 547 548 #ifdef ENABLE_CLASSIC_LEGACY_CONNECTIONS_FOR_SCO_DEMOS 549 printf("Disable BR/EDR Secure Connctions due to incompatibilities with SCO connections\n"); 550 gap_secure_connections_enable(false); 551 #endif 552 553 // Set SCO for CVSD (mSBC or other codecs automatically use 8-bit transparent mode) 554 hci_set_sco_voice_setting(0x60); // linear, unsigned, 16-bit, CVSD 555 556 // status 557 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE 558 printf("SCO Demo: Sending and receiving audio via btstack_audio.\n"); 559 #endif 560 #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 561 printf("SCO Demo: Sending sine wave, audio output via btstack_audio.\n"); 562 #endif 563 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MODPLAYER 564 printf("SCO Demo: Sending modplayer wave, audio output via btstack_audio.\n"); 565 // init mod 566 int hxcmod_initialized = hxcmod_init(&mod_context); 567 btstack_assert(hxcmod_initialized != 0); 568 #endif 569 } 570 571 void sco_demo_set_codec(uint8_t negotiated_codec){ 572 switch (negotiated_codec){ 573 case HFP_CODEC_CVSD: 574 codec_current = &codec_cvsd; 575 break; 576 #ifdef ENABLE_HFP_WIDE_BAND_SPEECH 577 case HFP_CODEC_MSBC: 578 codec_current = &codec_msbc; 579 break; 580 #endif 581 #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH 582 case HFP_CODEC_LC3_SWB: 583 codec_current = &codec_lc3swb; 584 break; 585 #endif 586 default: 587 btstack_assert(false); 588 break; 589 } 590 591 codec_current->init(); 592 593 audio_initialize(codec_current->sample_rate); 594 595 audio_prebuffer_bytes = SCO_PREBUFFER_MS * (codec_current->sample_rate/1000) * BYTES_PER_FRAME; 596 597 #ifdef SCO_WAV_FILENAME 598 num_samples_to_write = codec_current->sample_rate * SCO_WAV_DURATION_IN_SECONDS; 599 wav_writer_open(SCO_WAV_FILENAME, 1, codec_current->sample_rate); 600 #endif 601 602 #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 603 sine_wave_steps_per_sample = SINE_WAVE_SAMPLE_RATE / codec_current->sample_rate; 604 sco_demo_audio_generator = &sco_demo_sine_wave_host_endian; 605 #endif 606 607 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MODPLAYER 608 // load mod 609 hxcmod_setcfg(&mod_context, codec_current->sample_rate, 16, 1, 1, 1); 610 hxcmod_load(&mod_context, (void *) &mod_data, mod_len); 611 sco_demo_audio_generator = &sco_demo_modplayer; 612 #endif 613 } 614 615 void sco_demo_receive(uint8_t * packet, uint16_t size){ 616 static uint32_t packets = 0; 617 static uint32_t crc_errors = 0; 618 static uint32_t data_received = 0; 619 static uint32_t byte_errors = 0; 620 621 count_received++; 622 623 data_received += size - 3; 624 packets++; 625 if (data_received > 100000){ 626 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); 627 crc_errors = 0; 628 byte_errors = 0; 629 data_received = 0; 630 packets = 0; 631 } 632 633 codec_current->receive(packet, size); 634 } 635 636 void sco_demo_send(hci_con_handle_t sco_handle){ 637 638 if (sco_handle == HCI_CON_HANDLE_INVALID) return; 639 640 int sco_packet_length = hci_get_sco_packet_length(); 641 int sco_payload_length = sco_packet_length - 3; 642 643 hci_reserve_packet_buffer(); 644 uint8_t * sco_packet = hci_get_outgoing_packet_buffer(); 645 646 #ifdef USE_ADUIO_GENERATOR 647 #define REFILL_SAMPLES 16 648 // re-fill audio buffer 649 uint16_t samples_free = btstack_ring_buffer_bytes_free(&audio_input_ring_buffer) / 2; 650 while (samples_free > 0){ 651 int16_t samples_buffer[REFILL_SAMPLES]; 652 uint16_t samples_to_add = btstack_min(samples_free, REFILL_SAMPLES); 653 (*sco_demo_audio_generator)(samples_to_add, samples_buffer); 654 btstack_ring_buffer_write(&audio_input_ring_buffer, (uint8_t *)samples_buffer, samples_to_add * 2); 655 samples_free -= samples_to_add; 656 } 657 #endif 658 659 // resume if pre-buffer is filled 660 if (audio_input_paused){ 661 if (btstack_ring_buffer_bytes_available(&audio_input_ring_buffer) >= audio_prebuffer_bytes){ 662 // resume sending 663 audio_input_paused = 0; 664 } 665 } 666 667 // fill payload by codec 668 codec_current->fill_payload(&sco_packet[3], sco_payload_length); 669 670 // set handle + flags 671 little_endian_store_16(sco_packet, 0, sco_handle); 672 // set len 673 sco_packet[2] = sco_payload_length; 674 // finally send packet 675 hci_send_sco_packet_buffer(sco_packet_length); 676 677 // request another send event 678 hci_request_sco_can_send_now_event(); 679 680 count_sent++; 681 if ((count_sent % SCO_REPORT_PERIOD) == 0) { 682 printf("SCO: sent %u, received %u\n", count_sent, count_received); 683 } 684 } 685 686 void sco_demo_close(void){ 687 printf("SCO demo close\n"); 688 689 printf("SCO demo statistics: "); 690 codec_current->close(); 691 codec_current = NULL; 692 693 #if defined(SCO_WAV_FILENAME) 694 wav_writer_close(); 695 #endif 696 697 audio_terminate(); 698 } 699