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