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 _MSC_VER 57 // ignore deprecated warning for fopen 58 #pragma warning(disable : 4996) 59 #endif 60 61 #ifdef HAVE_POSIX_FILE_IO 62 #include "wav_util.h" 63 #endif 64 65 // test modes 66 #define SCO_DEMO_MODE_SINE 0 67 #define SCO_DEMO_MODE_MICROPHONE 1 68 #define SCO_DEMO_MODE_MODPLAYER 2 69 70 // SCO demo configuration 71 #define SCO_DEMO_MODE SCO_DEMO_MODE_MICROPHONE 72 73 // number of sco packets until 'report' on console 74 #define SCO_REPORT_PERIOD 100 75 76 77 #ifdef HAVE_POSIX_FILE_IO 78 // length and name of wav file on disk 79 #define SCO_WAV_DURATION_IN_SECONDS 15 80 #define SCO_WAV_FILENAME "sco_input.wav" 81 #endif 82 83 // constants 84 #define NUM_CHANNELS 1 85 #define SAMPLE_RATE_8KHZ 8000 86 #define SAMPLE_RATE_16KHZ 16000 87 #define BYTES_PER_FRAME 2 88 89 // pre-buffer for CVSD and mSBC - also defines latency 90 #define SCO_PREBUFFER_MS 50 91 #define PREBUFFER_BYTES_8KHZ (SCO_PREBUFFER_MS * SAMPLE_RATE_8KHZ/1000 * BYTES_PER_FRAME) 92 #define PREBUFFER_BYTES_16KHZ (SCO_PREBUFFER_MS * SAMPLE_RATE_16KHZ/1000 * BYTES_PER_FRAME) 93 94 #if defined(ENABLE_HFP_WIDE_BAND_SPEECH) 95 #define PREBUFFER_BYTES_MAX PREBUFFER_BYTES_16KHZ 96 #define SAMPLES_PER_FRAME_MAX 120 97 #else 98 #define PREBUFFER_BYTES_MAX PREBUFFER_BYTES_8KHZ 99 #define SAMPLES_PER_FRAME_MAX 60 100 #endif 101 102 static uint16_t audio_prebuffer_bytes; 103 104 // output 105 static int audio_output_paused = 0; 106 static uint8_t audio_output_ring_buffer_storage[2 * PREBUFFER_BYTES_MAX]; 107 static btstack_ring_buffer_t audio_output_ring_buffer; 108 109 // input 110 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE 111 #define USE_AUDIO_INPUT 112 #else 113 #define USE_ADUIO_GENERATOR 114 static void (*sco_demo_audio_generator)(uint16_t num_samples, int16_t * data); 115 #endif 116 static int audio_input_paused = 0; 117 static uint8_t audio_input_ring_buffer_storage[2 * PREBUFFER_BYTES_MAX]; 118 static btstack_ring_buffer_t audio_input_ring_buffer; 119 120 // mod player 121 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MODPLAYER 122 #include "hxcmod.h" 123 #include "mods/mod.h" 124 static modcontext mod_context; 125 #endif 126 127 static int count_sent = 0; 128 static int count_received = 0; 129 130 #ifdef ENABLE_HFP_WIDE_BAND_SPEECH 131 #define MSBC_MAX_NUM_SAMPLES (16*8) 132 static btstack_sbc_decoder_state_t decoder_state; 133 #endif 134 135 static btstack_cvsd_plc_state_t cvsd_plc_state; 136 137 int num_samples_to_write; 138 int num_audio_frames; 139 140 // generic codec support 141 typedef struct { 142 void (*init)(void); 143 void(*receive)(const uint8_t * packet, uint16_t size); 144 void (*fill_payload)(uint8_t * payload_buffer, uint16_t sco_payload_length); 145 void (*close)(void); 146 // 147 uint16_t sample_rate; 148 } codec_support_t; 149 150 // current configuration 151 static const codec_support_t * codec_current = NULL; 152 153 // hfp_codec 154 static hfp_codec_t hfp_codec; 155 156 // Sine Wave 157 158 #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 159 static uint16_t sine_wave_phase; 160 static uint16_t sine_wave_steps_per_sample; 161 #define SINE_WAVE_SAMPLE_RATE SAMPLE_RATE_16KHZ 162 163 // input signal: pre-computed sine wave, 266 Hz at 16000 kHz 164 static const int16_t sine_int16_at_16000hz[] = { 165 0, 3135, 6237, 9270, 12202, 14999, 17633, 20073, 22294, 24270, 166 25980, 27406, 28531, 29344, 29835, 30000, 29835, 29344, 28531, 27406, 167 25980, 24270, 22294, 20073, 17633, 14999, 12202, 9270, 6237, 3135, 168 0, -3135, -6237, -9270, -12202, -14999, -17633, -20073, -22294, -24270, 169 -25980, -27406, -28531, -29344, -29835, -30000, -29835, -29344, -28531, -27406, 170 -25980, -24270, -22294, -20073, -17633, -14999, -12202, -9270, -6237, -3135, 171 }; 172 173 static void sco_demo_sine_wave_host_endian(uint16_t num_samples, int16_t * data){ 174 unsigned int i; 175 for (i=0; i < num_samples; i++){ 176 data[i] = sine_int16_at_16000hz[sine_wave_phase]; 177 sine_wave_phase += sine_wave_steps_per_sample; 178 if (sine_wave_phase >= (sizeof(sine_int16_at_16000hz) / sizeof(int16_t))){ 179 sine_wave_phase = 0; 180 } 181 } 182 } 183 #endif 184 185 // Mod Player 186 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MODPLAYER 187 #define NUM_SAMPLES_GENERATOR_BUFFER 30 188 static void sco_demo_modplayer(uint16_t num_samples, int16_t * data){ 189 // mix down stereo 190 signed short samples[NUM_SAMPLES_GENERATOR_BUFFER * 2]; 191 while (num_samples > 0){ 192 uint16_t next_samples = btstack_min(num_samples, NUM_SAMPLES_GENERATOR_BUFFER); 193 hxcmod_fillbuffer(&mod_context, (unsigned short *) samples, next_samples, NULL); 194 num_samples -= next_samples; 195 uint16_t i; 196 for (i=0;i<next_samples;i++){ 197 int32_t left = samples[2*i + 0]; 198 int32_t right = samples[2*i + 1]; 199 data[i] = (int16_t)((left + right) / 2); 200 } 201 } 202 } 203 #endif 204 205 // Audio Playback / Recording 206 207 static void audio_playback_callback(int16_t * buffer, uint16_t num_samples){ 208 209 // fill with silence while paused 210 if (audio_output_paused){ 211 if (btstack_ring_buffer_bytes_available(&audio_output_ring_buffer) < audio_prebuffer_bytes){ 212 memset(buffer, 0, num_samples * BYTES_PER_FRAME); 213 return; 214 } else { 215 // resume playback 216 audio_output_paused = 0; 217 } 218 } 219 220 // get data from ringbuffer 221 uint32_t bytes_read = 0; 222 btstack_ring_buffer_read(&audio_output_ring_buffer, (uint8_t *) buffer, num_samples * BYTES_PER_FRAME, &bytes_read); 223 num_samples -= bytes_read / BYTES_PER_FRAME; 224 buffer += bytes_read / BYTES_PER_FRAME; 225 226 // fill with 0 if not enough 227 if (num_samples){ 228 memset(buffer, 0, num_samples * BYTES_PER_FRAME); 229 audio_output_paused = 1; 230 } 231 } 232 233 #ifdef USE_AUDIO_INPUT 234 static void audio_recording_callback(const int16_t * buffer, uint16_t num_samples){ 235 btstack_ring_buffer_write(&audio_input_ring_buffer, (uint8_t *)buffer, num_samples * 2); 236 } 237 #endif 238 239 // return 1 if ok 240 static int audio_initialize(int sample_rate){ 241 242 // -- output -- // 243 244 // init buffers 245 memset(audio_output_ring_buffer_storage, 0, sizeof(audio_output_ring_buffer_storage)); 246 btstack_ring_buffer_init(&audio_output_ring_buffer, audio_output_ring_buffer_storage, sizeof(audio_output_ring_buffer_storage)); 247 248 // config and setup audio playback 249 const btstack_audio_sink_t * audio_sink = btstack_audio_sink_get_instance(); 250 if (!audio_sink) return 0; 251 252 audio_sink->init(1, sample_rate, &audio_playback_callback); 253 audio_sink->start_stream(); 254 255 audio_output_paused = 1; 256 257 // -- input -- // 258 259 // init buffers 260 memset(audio_input_ring_buffer_storage, 0, sizeof(audio_input_ring_buffer_storage)); 261 btstack_ring_buffer_init(&audio_input_ring_buffer, audio_input_ring_buffer_storage, sizeof(audio_input_ring_buffer_storage)); 262 audio_input_paused = 1; 263 264 #ifdef USE_AUDIO_INPUT 265 // config and setup audio recording 266 const btstack_audio_source_t * audio_source = btstack_audio_source_get_instance(); 267 if (!audio_source) return 0; 268 269 audio_source->init(1, sample_rate, &audio_recording_callback); 270 audio_source->start_stream(); 271 #endif 272 273 return 1; 274 } 275 276 static void audio_terminate(void){ 277 const btstack_audio_sink_t * audio_sink = btstack_audio_sink_get_instance(); 278 if (!audio_sink) return; 279 audio_sink->close(); 280 281 #ifdef USE_AUDIO_INPUT 282 const btstack_audio_source_t * audio_source= btstack_audio_source_get_instance(); 283 if (!audio_source) return; 284 audio_source->close(); 285 #endif 286 } 287 288 289 // CVSD - 8 kHz 290 291 static void sco_demo_cvsd_init(void){ 292 printf("SCO Demo: Init CVSD\n"); 293 btstack_cvsd_plc_init(&cvsd_plc_state); 294 } 295 296 static void sco_demo_cvsd_receive(const uint8_t * packet, uint16_t size){ 297 298 int16_t audio_frame_out[128]; // 299 300 if (size > sizeof(audio_frame_out)){ 301 printf("sco_demo_cvsd_receive: SCO packet larger than local output buffer - dropping data.\n"); 302 return; 303 } 304 305 const int audio_bytes_read = size - 3; 306 const int num_samples = audio_bytes_read / BYTES_PER_FRAME; 307 308 // convert into host endian 309 int16_t audio_frame_in[128]; 310 int i; 311 for (i=0;i<num_samples;i++){ 312 audio_frame_in[i] = little_endian_read_16(packet, 3 + i * 2); 313 } 314 315 // treat packet as bad frame if controller does not report 'all good' 316 bool bad_frame = (packet[1] & 0x30) != 0; 317 318 btstack_cvsd_plc_process_data(&cvsd_plc_state, bad_frame, audio_frame_in, num_samples, audio_frame_out); 319 320 #ifdef SCO_WAV_FILENAME 321 // Samples in CVSD SCO packet are in little endian, ready for wav files (take shortcut) 322 const int samples_to_write = btstack_min(num_samples, num_samples_to_write); 323 wav_writer_write_le_int16(samples_to_write, audio_frame_out); 324 num_samples_to_write -= samples_to_write; 325 if (num_samples_to_write == 0){ 326 wav_writer_close(); 327 } 328 #endif 329 330 btstack_ring_buffer_write(&audio_output_ring_buffer, (uint8_t *)audio_frame_out, audio_bytes_read); 331 } 332 333 static void sco_demo_cvsd_fill_payload(uint8_t * payload_buffer, uint16_t sco_payload_length){ 334 uint16_t bytes_to_copy = sco_payload_length; 335 336 // get data from ringbuffer 337 uint16_t pos = 0; 338 if (!audio_input_paused){ 339 uint16_t samples_to_copy = sco_payload_length / 2; 340 uint32_t bytes_read = 0; 341 btstack_ring_buffer_read(&audio_input_ring_buffer, payload_buffer, bytes_to_copy, &bytes_read); 342 // flip 16 on big endian systems 343 // @note We don't use (uint16_t *) casts since all sample addresses are odd which causes crahses on some systems 344 if (btstack_is_big_endian()){ 345 uint16_t i; 346 for (i=0;i<samples_to_copy/2;i+=2){ 347 uint8_t tmp = payload_buffer[i*2]; 348 payload_buffer[i*2] = payload_buffer[i*2+1]; 349 payload_buffer[i*2+1] = tmp; 350 } 351 } 352 bytes_to_copy -= bytes_read; 353 pos += bytes_read; 354 } 355 356 // fill with 0 if not enough 357 if (bytes_to_copy){ 358 memset(payload_buffer + pos, 0, bytes_to_copy); 359 audio_input_paused = 1; 360 } 361 } 362 363 static void sco_demo_cvsd_close(void){ 364 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); 365 } 366 367 static const codec_support_t codec_cvsd = { 368 .init = &sco_demo_cvsd_init, 369 .receive = &sco_demo_cvsd_receive, 370 .fill_payload = &sco_demo_cvsd_fill_payload, 371 .close = &sco_demo_cvsd_close, 372 .sample_rate = SAMPLE_RATE_8KHZ 373 }; 374 375 // mSBC - 16 kHz 376 377 #ifdef ENABLE_HFP_WIDE_BAND_SPEECH 378 379 static void handle_pcm_data(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context){ 380 UNUSED(context); 381 UNUSED(sample_rate); 382 UNUSED(data); 383 UNUSED(num_samples); 384 UNUSED(num_channels); 385 386 // samples in callback in host endianess, ready for playback 387 btstack_ring_buffer_write(&audio_output_ring_buffer, (uint8_t *)data, num_samples*num_channels*2); 388 389 #ifdef SCO_WAV_FILENAME 390 if (!num_samples_to_write) return; 391 num_samples = btstack_min(num_samples, num_samples_to_write); 392 num_samples_to_write -= num_samples; 393 wav_writer_write_int16(num_samples, data); 394 if (num_samples_to_write == 0){ 395 wav_writer_close(); 396 } 397 #endif /* SCO_WAV_FILENAME */ 398 } 399 400 static void sco_demo_msbc_init(void){ 401 printf("SCO Demo: Init mSBC\n"); 402 btstack_sbc_decoder_init(&decoder_state, SBC_MODE_mSBC, &handle_pcm_data, NULL); 403 hfp_codec_init(&hfp_codec, HFP_CODEC_MSBC); 404 } 405 406 static void sco_demo_msbc_receive(const uint8_t * packet, uint16_t size){ 407 btstack_sbc_decoder_process_data(&decoder_state, (packet[1] >> 4) & 3, packet+3, size-3); 408 } 409 410 void sco_demo_msbc_fill_payload(uint8_t * payload_buffer, uint16_t sco_payload_length){ 411 if (!audio_input_paused){ 412 int num_samples = hfp_codec_num_audio_samples_per_frame(&hfp_codec); 413 btstack_assert(num_samples <= SAMPLES_PER_FRAME_MAX); 414 uint16_t samples_available = btstack_ring_buffer_bytes_available(&audio_input_ring_buffer) / BYTES_PER_FRAME; 415 if (hfp_codec_can_encode_audio_frame_now(&hfp_codec) && samples_available >= num_samples){ 416 int16_t sample_buffer[SAMPLES_PER_FRAME_MAX]; 417 uint32_t bytes_read; 418 btstack_ring_buffer_read(&audio_input_ring_buffer, (uint8_t*) sample_buffer, num_samples * BYTES_PER_FRAME, &bytes_read); 419 hfp_codec_encode_audio_frame(&hfp_codec, sample_buffer); 420 num_audio_frames++; 421 } 422 } 423 424 // get data from encoder, fill with 0 if not enough 425 if (audio_input_paused || hfp_codec_num_bytes_available(&hfp_codec) < sco_payload_length){ 426 // just send '0's 427 memset(payload_buffer, 0, sco_payload_length); 428 audio_input_paused = 1; 429 } else { 430 hfp_codec_read_from_stream(&hfp_codec, payload_buffer, sco_payload_length); 431 } 432 } 433 434 static void sco_demo_msbc_close(void){ 435 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); 436 } 437 438 static const codec_support_t codec_msbc = { 439 .init = &sco_demo_msbc_init, 440 .receive = &sco_demo_msbc_receive, 441 .fill_payload = &sco_demo_msbc_fill_payload, 442 .close = &sco_demo_msbc_close, 443 .sample_rate = SAMPLE_RATE_16KHZ 444 }; 445 446 #endif /* ENABLE_HFP_WIDE_BAND_SPEECH */ 447 448 void sco_demo_init(void){ 449 450 #ifdef ENABLE_CLASSIC_LEGACY_CONNECTIONS_FOR_SCO_DEMOS 451 printf("Disable BR/EDR Secure Connctions due to incompatibilities with SCO connections\n"); 452 gap_secure_connections_enable(false); 453 #endif 454 455 // status 456 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MICROPHONE 457 printf("SCO Demo: Sending and receiving audio via btstack_audio.\n"); 458 #endif 459 #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 460 if (btstack_audio_sink_get_instance()){ 461 printf("SCO Demo: Sending sine wave, audio output via btstack_audio.\n"); 462 } else { 463 printf("SCO Demo: Sending sine wave, hexdump received data.\n"); 464 } 465 #endif 466 467 // Set SCO for CVSD (mSBC or other codecs automatically use 8-bit transparent mode) 468 hci_set_sco_voice_setting(0x60); // linear, unsigned, 16-bit, CVSD 469 470 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MODPLAYER 471 // init mod 472 int hxcmod_initialized = hxcmod_init(&mod_context); 473 btstack_assert(hxcmod_initialized != 0); 474 #endif 475 } 476 477 void sco_demo_set_codec(uint8_t negotiated_codec){ 478 switch (negotiated_codec){ 479 case HFP_CODEC_CVSD: 480 codec_current = &codec_cvsd; 481 break; 482 #ifdef ENABLE_HFP_WIDE_BAND_SPEECH 483 case HFP_CODEC_MSBC: 484 codec_current = &codec_msbc; 485 break; 486 #endif 487 default: 488 btstack_assert(false); 489 break; 490 } 491 492 codec_current->init(); 493 494 audio_initialize(codec_current->sample_rate); 495 496 audio_prebuffer_bytes = SCO_PREBUFFER_MS * (codec_current->sample_rate/1000) * BYTES_PER_FRAME; 497 498 #ifdef SCO_WAV_FILENAME 499 num_samples_to_write = codec_current->sample_rate * SCO_WAV_DURATION_IN_SECONDS; 500 wav_writer_open(SCO_WAV_FILENAME, 1, codec_current->sample_rate); 501 #endif 502 503 #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 504 sine_wave_steps_per_sample = SINE_WAVE_SAMPLE_RATE / codec_current->sample_rate; 505 sco_demo_audio_generator = &sco_demo_sine_wave_host_endian; 506 #endif 507 508 #if SCO_DEMO_MODE == SCO_DEMO_MODE_MODPLAYER 509 // load mod 510 hxcmod_setcfg(&mod_context, codec_current->sample_rate, 16, 1, 1, 1); 511 hxcmod_load(&mod_context, (void *) &mod_data, mod_len); 512 sco_demo_audio_generator = &sco_demo_modplayer; 513 #endif 514 } 515 516 void sco_demo_receive(uint8_t * packet, uint16_t size){ 517 static uint32_t packets = 0; 518 static uint32_t crc_errors = 0; 519 static uint32_t data_received = 0; 520 static uint32_t byte_errors = 0; 521 522 count_received++; 523 524 data_received += size - 3; 525 packets++; 526 if (data_received > 100000){ 527 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); 528 crc_errors = 0; 529 byte_errors = 0; 530 data_received = 0; 531 packets = 0; 532 } 533 534 codec_current->receive(packet, size); 535 } 536 537 void sco_demo_send(hci_con_handle_t sco_handle){ 538 539 if (sco_handle == HCI_CON_HANDLE_INVALID) return; 540 541 int sco_packet_length = hci_get_sco_packet_length(); 542 int sco_payload_length = sco_packet_length - 3; 543 544 hci_reserve_packet_buffer(); 545 uint8_t * sco_packet = hci_get_outgoing_packet_buffer(); 546 547 #ifdef USE_ADUIO_GENERATOR 548 #define REFILL_SAMPLES 16 549 // re-fill audio buffer 550 uint16_t samples_free = btstack_ring_buffer_bytes_free(&audio_input_ring_buffer) / 2; 551 while (samples_free > 0){ 552 int16_t samples_buffer[REFILL_SAMPLES]; 553 uint16_t samples_to_add = btstack_min(samples_free, REFILL_SAMPLES); 554 (*sco_demo_audio_generator)(samples_to_add, samples_buffer); 555 btstack_ring_buffer_write(&audio_input_ring_buffer, (uint8_t *)samples_buffer, samples_to_add * 2); 556 samples_free -= samples_to_add; 557 } 558 #endif 559 560 // resume if pre-buffer is filled 561 if (audio_input_paused){ 562 if (btstack_ring_buffer_bytes_available(&audio_input_ring_buffer) >= audio_prebuffer_bytes){ 563 // resume sending 564 audio_input_paused = 0; 565 } 566 } 567 568 // fill payload by codec 569 codec_current->fill_payload(&sco_packet[3], sco_payload_length); 570 571 // set handle + flags 572 little_endian_store_16(sco_packet, 0, sco_handle); 573 // set len 574 sco_packet[2] = sco_payload_length; 575 // finally send packet 576 hci_send_sco_packet_buffer(sco_packet_length); 577 578 // request another send event 579 hci_request_sco_can_send_now_event(); 580 581 count_sent++; 582 if ((count_sent % SCO_REPORT_PERIOD) == 0) { 583 printf("SCO: sent %u, received %u\n", count_sent, count_received); 584 } 585 } 586 587 void sco_demo_close(void){ 588 printf("SCO demo close\n"); 589 590 printf("SCO demo statistics: "); 591 codec_current->close(); 592 codec_current = NULL; 593 594 #if defined(SCO_WAV_FILENAME) 595 wav_writer_close(); 596 #endif 597 598 audio_terminate(); 599 } 600