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