1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #ifndef _WIN32 15 #include <unistd.h> 16 #endif 17 18 #include <vector> 19 20 #include "gflags/gflags.h" 21 #include "testing/gtest/include/gtest/gtest.h" 22 #include "webrtc/base/format_macros.h" 23 #include "webrtc/base/scoped_ptr.h" 24 #include "webrtc/call/rtc_event_log.h" 25 #include "webrtc/engine_configurations.h" 26 #include "webrtc/modules/audio_processing/include/audio_processing.h" 27 #include "webrtc/test/channel_transport/channel_transport.h" 28 #include "webrtc/test/testsupport/fileutils.h" 29 #include "webrtc/test/testsupport/trace_to_stderr.h" 30 #include "webrtc/voice_engine/include/voe_audio_processing.h" 31 #include "webrtc/voice_engine/include/voe_base.h" 32 #include "webrtc/voice_engine/include/voe_codec.h" 33 #include "webrtc/voice_engine/include/voe_dtmf.h" 34 #include "webrtc/voice_engine/include/voe_errors.h" 35 #include "webrtc/voice_engine/include/voe_external_media.h" 36 #include "webrtc/voice_engine/include/voe_file.h" 37 #include "webrtc/voice_engine/include/voe_hardware.h" 38 #include "webrtc/voice_engine/include/voe_neteq_stats.h" 39 #include "webrtc/voice_engine/include/voe_network.h" 40 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" 41 #include "webrtc/voice_engine/include/voe_video_sync.h" 42 #include "webrtc/voice_engine/include/voe_volume_control.h" 43 44 DEFINE_bool(use_log_file, false, 45 "Output logs to a file; by default they will be printed to stderr."); 46 47 using namespace webrtc; 48 using namespace test; 49 50 #define VALIDATE \ 51 if (res != 0) { \ 52 printf("*** Error at line %i \n", __LINE__); \ 53 printf("*** Error code = %i \n", base1->LastError()); \ 54 } 55 56 VoiceEngine* m_voe = NULL; 57 VoEBase* base1 = NULL; 58 VoECodec* codec = NULL; 59 VoEVolumeControl* volume = NULL; 60 VoEDtmf* dtmf = NULL; 61 VoERTP_RTCP* rtp_rtcp = NULL; 62 VoEAudioProcessing* apm = NULL; 63 VoENetwork* netw = NULL; 64 VoEFile* file = NULL; 65 VoEVideoSync* vsync = NULL; 66 VoEHardware* hardware = NULL; 67 VoEExternalMedia* xmedia = NULL; 68 VoENetEqStats* neteqst = NULL; 69 70 void RunTest(std::string out_path); 71 72 class MyObserver : public VoiceEngineObserver { 73 public: 74 virtual void CallbackOnError(int channel, int err_code); 75 }; 76 77 void MyObserver::CallbackOnError(int channel, int err_code) { 78 // Add printf for other error codes here 79 if (err_code == VE_TYPING_NOISE_WARNING) { 80 printf(" TYPING NOISE DETECTED \n"); 81 } else if (err_code == VE_TYPING_NOISE_OFF_WARNING) { 82 printf(" TYPING NOISE OFF DETECTED \n"); 83 } else if (err_code == VE_RECEIVE_PACKET_TIMEOUT) { 84 printf(" RECEIVE PACKET TIMEOUT \n"); 85 } else if (err_code == VE_PACKET_RECEIPT_RESTARTED) { 86 printf(" PACKET RECEIPT RESTARTED \n"); 87 } else if (err_code == VE_RUNTIME_PLAY_WARNING) { 88 printf(" RUNTIME PLAY WARNING \n"); 89 } else if (err_code == VE_RUNTIME_REC_WARNING) { 90 printf(" RUNTIME RECORD WARNING \n"); 91 } else if (err_code == VE_SATURATION_WARNING) { 92 printf(" SATURATION WARNING \n"); 93 } else if (err_code == VE_RUNTIME_PLAY_ERROR) { 94 printf(" RUNTIME PLAY ERROR \n"); 95 } else if (err_code == VE_RUNTIME_REC_ERROR) { 96 printf(" RUNTIME RECORD ERROR \n"); 97 } else if (err_code == VE_REC_DEVICE_REMOVED) { 98 printf(" RECORD DEVICE REMOVED \n"); 99 } 100 } 101 102 void SetStereoIfOpus(bool use_stereo, CodecInst* codec_params) { 103 if (strncmp(codec_params->plname, "opus", 4) == 0) { 104 if (use_stereo) 105 codec_params->channels = 2; 106 else 107 codec_params->channels = 1; 108 } 109 } 110 111 void PrintCodecs(bool opus_stereo) { 112 CodecInst codec_params; 113 for (int i = 0; i < codec->NumOfCodecs(); ++i) { 114 int res = codec->GetCodec(i, codec_params); 115 VALIDATE; 116 SetStereoIfOpus(opus_stereo, &codec_params); 117 printf("%2d. %3d %s/%d/%" PRIuS " \n", i, codec_params.pltype, 118 codec_params.plname, codec_params.plfreq, codec_params.channels); 119 } 120 } 121 122 int main(int argc, char** argv) { 123 google::ParseCommandLineFlags(&argc, &argv, true); 124 125 int res = 0; 126 127 printf("Test started \n"); 128 129 m_voe = VoiceEngine::Create(); 130 base1 = VoEBase::GetInterface(m_voe); 131 codec = VoECodec::GetInterface(m_voe); 132 apm = VoEAudioProcessing::GetInterface(m_voe); 133 volume = VoEVolumeControl::GetInterface(m_voe); 134 dtmf = VoEDtmf::GetInterface(m_voe); 135 rtp_rtcp = VoERTP_RTCP::GetInterface(m_voe); 136 netw = VoENetwork::GetInterface(m_voe); 137 file = VoEFile::GetInterface(m_voe); 138 vsync = VoEVideoSync::GetInterface(m_voe); 139 hardware = VoEHardware::GetInterface(m_voe); 140 xmedia = VoEExternalMedia::GetInterface(m_voe); 141 neteqst = VoENetEqStats::GetInterface(m_voe); 142 143 MyObserver my_observer; 144 145 rtc::scoped_ptr<test::TraceToStderr> trace_to_stderr; 146 if (!FLAGS_use_log_file) { 147 trace_to_stderr.reset(new test::TraceToStderr); 148 } else { 149 const std::string trace_filename = test::OutputPath() + "webrtc_trace.txt"; 150 VoiceEngine::SetTraceFilter(kTraceAll); 151 res = VoiceEngine::SetTraceFile(trace_filename.c_str()); 152 VALIDATE; 153 res = VoiceEngine::SetTraceCallback(NULL); 154 VALIDATE; 155 printf("Outputting logs to file: %s\n", trace_filename.c_str()); 156 } 157 158 printf("Init\n"); 159 res = base1->Init(); 160 if (res != 0) { 161 printf("\nError calling Init: %d\n", base1->LastError()); 162 fflush(NULL); 163 exit(1); 164 } 165 166 res = base1->RegisterVoiceEngineObserver(my_observer); 167 VALIDATE; 168 169 printf("Version\n"); 170 char tmp[1024]; 171 res = base1->GetVersion(tmp); 172 VALIDATE; 173 printf("%s\n", tmp); 174 175 RunTest(test::OutputPath()); 176 177 printf("Terminate \n"); 178 179 base1->DeRegisterVoiceEngineObserver(); 180 181 res = base1->Terminate(); 182 VALIDATE; 183 184 if (base1) 185 base1->Release(); 186 187 if (codec) 188 codec->Release(); 189 190 if (volume) 191 volume->Release(); 192 193 if (dtmf) 194 dtmf->Release(); 195 196 if (rtp_rtcp) 197 rtp_rtcp->Release(); 198 199 if (apm) 200 apm->Release(); 201 202 if (netw) 203 netw->Release(); 204 205 if (file) 206 file->Release(); 207 208 if (vsync) 209 vsync->Release(); 210 211 if (hardware) 212 hardware->Release(); 213 214 if (xmedia) 215 xmedia->Release(); 216 217 if (neteqst) 218 neteqst->Release(); 219 220 VoiceEngine::Delete(m_voe); 221 222 return 0; 223 } 224 225 void RunTest(std::string out_path) { 226 int chan, res; 227 CodecInst cinst; 228 bool enable_aec = false; 229 bool enable_agc = false; 230 bool enable_rx_agc = false; 231 bool enable_cng = false; 232 bool enable_ns = false; 233 bool enable_rx_ns = false; 234 bool typing_detection = false; 235 bool muted = false; 236 bool opus_stereo = false; 237 bool opus_dtx = false; 238 bool experimental_ns_enabled = false; 239 bool debug_recording_started = false; 240 241 #if defined(WEBRTC_ANDROID) 242 std::string resource_path = "/sdcard/"; 243 #else 244 std::string resource_path = webrtc::test::ProjectRootPath(); 245 if (resource_path == webrtc::test::kCannotFindProjectRootDir) { 246 printf("*** Unable to get project root directory. " 247 "File playing may fail. ***\n"); 248 // Fall back to the current directory. 249 resource_path = "./"; 250 } else { 251 resource_path += "data/voice_engine/"; 252 } 253 #endif 254 const std::string audio_filename = resource_path + "audio_long16.pcm"; 255 256 const std::string play_filename = out_path + "recorded_playout.pcm"; 257 const std::string mic_filename = out_path + "recorded_mic.pcm"; 258 259 chan = base1->CreateChannel(); 260 if (chan < 0) { 261 printf("************ Error code = %i\n", base1->LastError()); 262 fflush(NULL); 263 } 264 265 VoiceChannelTransport* voice_channel_transport( 266 new VoiceChannelTransport(netw, chan)); 267 268 char ip[64]; 269 printf("1. 127.0.0.1 \n"); 270 printf("2. Specify IP \n"); 271 int ip_selection; 272 ASSERT_EQ(1, scanf("%i", &ip_selection)); 273 274 if (ip_selection == 1) { 275 strcpy(ip, "127.0.0.1"); 276 } else { 277 printf("Specify remote IP: "); 278 ASSERT_EQ(1, scanf("%s", ip)); 279 } 280 281 int rPort; 282 printf("Specify remote port (1=1234): "); 283 ASSERT_EQ(1, scanf("%i", &rPort)); 284 if (1 == rPort) 285 rPort = 1234; 286 printf("Set Send port \n"); 287 288 printf("Set Send IP \n"); 289 res = voice_channel_transport->SetSendDestination(ip, rPort); 290 VALIDATE; 291 292 int lPort; 293 printf("Specify local port (1=1234): "); 294 ASSERT_EQ(1, scanf("%i", &lPort)); 295 if (1 == lPort) 296 lPort = 1234; 297 printf("Set Rec Port \n"); 298 299 res = voice_channel_transport->SetLocalReceiver(lPort); 300 VALIDATE; 301 302 printf("\n"); 303 PrintCodecs(opus_stereo); 304 printf("Select send codec: "); 305 int codec_selection; 306 ASSERT_EQ(1, scanf("%i", &codec_selection)); 307 codec->GetCodec(codec_selection, cinst); 308 309 printf("Set primary codec\n"); 310 SetStereoIfOpus(opus_stereo, &cinst); 311 res = codec->SetSendCodec(chan, cinst); 312 VALIDATE; 313 314 const int kMaxNumChannels = 8; 315 int channel_index = 0; 316 std::vector<int> channels(kMaxNumChannels); 317 std::vector<VoiceChannelTransport*> voice_channel_transports(kMaxNumChannels); 318 319 for (int i = 0; i < kMaxNumChannels; ++i) { 320 channels[i] = base1->CreateChannel(); 321 int port = rPort + (i + 1) * 2; 322 323 voice_channel_transports[i] = new VoiceChannelTransport(netw, channels[i]); 324 325 res = voice_channel_transports[i]->SetSendDestination(ip, port); 326 VALIDATE; 327 res = voice_channel_transports[i]->SetLocalReceiver(port); 328 VALIDATE; 329 res = codec->SetSendCodec(channels[i], cinst); 330 VALIDATE; 331 } 332 333 // Call loop 334 bool newcall = true; 335 while (newcall) { 336 int rd(-1), pd(-1); 337 res = hardware->GetNumOfRecordingDevices(rd); 338 VALIDATE; 339 res = hardware->GetNumOfPlayoutDevices(pd); 340 VALIDATE; 341 342 char dn[128] = { 0 }; 343 char guid[128] = { 0 }; 344 printf("\nPlayout devices (%d): \n", pd); 345 for (int j = 0; j < pd; ++j) { 346 res = hardware->GetPlayoutDeviceName(j, dn, guid); 347 VALIDATE; 348 printf(" %d: %s \n", j, dn); 349 } 350 351 printf("Recording devices (%d): \n", rd); 352 for (int j = 0; j < rd; ++j) { 353 res = hardware->GetRecordingDeviceName(j, dn, guid); 354 VALIDATE; 355 printf(" %d: %s \n", j, dn); 356 } 357 358 printf("Select playout device: "); 359 ASSERT_EQ(1, scanf("%d", &pd)); 360 res = hardware->SetPlayoutDevice(pd); 361 VALIDATE; 362 printf("Select recording device: "); 363 ASSERT_EQ(1, scanf("%d", &rd)); 364 printf("Setting sound devices \n"); 365 res = hardware->SetRecordingDevice(rd); 366 VALIDATE; 367 368 res = codec->SetVADStatus(0, enable_cng); 369 VALIDATE; 370 371 res = apm->SetAgcStatus(enable_agc); 372 VALIDATE; 373 374 res = apm->SetEcStatus(enable_aec); 375 VALIDATE; 376 377 res = apm->SetNsStatus(enable_ns); 378 VALIDATE; 379 380 printf("\n1. Send, listen and playout \n"); 381 printf("2. Send only \n"); 382 printf("3. Listen and playout only \n"); 383 printf("Select transfer mode: "); 384 int call_selection; 385 ASSERT_EQ(1, scanf("%i", &call_selection)); 386 const bool send = !(call_selection == 3); 387 const bool receive = !(call_selection == 2); 388 389 if (receive) { 390 #ifndef EXTERNAL_TRANSPORT 391 printf("Start Listen \n"); 392 res = base1->StartReceive(chan); 393 VALIDATE; 394 #endif 395 396 printf("Start Playout \n"); 397 res = base1->StartPlayout(chan); 398 VALIDATE; 399 } 400 401 if (send) { 402 printf("Start Send \n"); 403 res = base1->StartSend(chan); 404 VALIDATE; 405 } 406 407 printf("Getting mic volume \n"); 408 unsigned int vol = 999; 409 res = volume->GetMicVolume(vol); 410 VALIDATE; 411 if ((vol > 255) || (vol < 1)) { 412 printf("\n****ERROR in GetMicVolume"); 413 } 414 415 int forever = 1; 416 while (forever) { 417 printf("\nSelect codec\n"); 418 PrintCodecs(opus_stereo); 419 printf("\nOther actions\n"); 420 const int num_codecs = codec->NumOfCodecs(); 421 int option_index = num_codecs; 422 printf("%i. Toggle CNG\n", option_index++); 423 printf("%i. Toggle AGC\n", option_index++); 424 printf("%i. Toggle NS\n", option_index++); 425 printf("%i. Toggle experimental NS\n", option_index++); 426 printf("%i. Toggle EC\n", option_index++); 427 printf("%i. Select AEC\n", option_index++); 428 printf("%i. Select AECM\n", option_index++); 429 printf("%i. Get speaker volume\n", option_index++); 430 printf("%i. Set speaker volume\n", option_index++); 431 printf("%i. Get microphone volume\n", option_index++); 432 printf("%i. Set microphone volume\n", option_index++); 433 printf("%i. Play local file (audio_long16.pcm) \n", option_index++); 434 printf("%i. Change playout device \n", option_index++); 435 printf("%i. Change recording device \n", option_index++); 436 printf("%i. Toggle receive-side AGC \n", option_index++); 437 printf("%i. Toggle receive-side NS \n", option_index++); 438 printf("%i. AGC status \n", option_index++); 439 printf("%i. Toggle microphone mute \n", option_index++); 440 printf("%i. Get last error code \n", option_index++); 441 printf("%i. Toggle typing detection \n", 442 option_index++); 443 printf("%i. Record a PCM file \n", option_index++); 444 printf("%i. Play a previously recorded PCM file locally \n", 445 option_index++); 446 printf("%i. Play a previously recorded PCM file as microphone \n", 447 option_index++); 448 printf("%i. Add an additional file-playing channel \n", option_index++); 449 printf("%i. Remove a file-playing channel \n", option_index++); 450 printf("%i. Toggle Opus stereo (Opus must be selected again to apply " 451 "the setting) \n", option_index++); 452 printf("%i. Set Opus maximum playback rate \n", option_index++); 453 printf("%i. Toggle Opus DTX \n", option_index++); 454 printf("%i. Set bit rate (only take effect on codecs that allow the " 455 "change) \n", option_index++); 456 printf("%i. Toggle AECdump recording \n", option_index++); 457 printf("%i. Record RtcEventLog file of 30 seconds \n", option_index++); 458 459 printf("Select action or %i to stop the call: ", option_index); 460 int option_selection; 461 ASSERT_EQ(1, scanf("%i", &option_selection)); 462 463 option_index = num_codecs; 464 if (option_selection < option_index) { 465 res = codec->GetCodec(option_selection, cinst); 466 VALIDATE; 467 if (strcmp(cinst.plname, "red") == 0) { 468 printf("Enabling RED\n"); 469 res = rtp_rtcp->SetREDStatus(chan, true, cinst.pltype); 470 } else { 471 SetStereoIfOpus(opus_stereo, &cinst); 472 printf("Set primary codec\n"); 473 res = codec->SetSendCodec(chan, cinst); 474 } 475 VALIDATE; 476 } else if (option_selection == option_index++) { 477 enable_cng = !enable_cng; 478 res = codec->SetVADStatus(0, enable_cng); 479 VALIDATE; 480 if (enable_cng) 481 printf("\n CNG is now on! \n"); 482 else 483 printf("\n CNG is now off! \n"); 484 } else if (option_selection == option_index++) { 485 enable_agc = !enable_agc; 486 res = apm->SetAgcStatus(enable_agc); 487 VALIDATE; 488 if (enable_agc) 489 printf("\n AGC is now on! \n"); 490 else 491 printf("\n AGC is now off! \n"); 492 } else if (option_selection == option_index++) { 493 enable_ns = !enable_ns; 494 res = apm->SetNsStatus(enable_ns); 495 VALIDATE; 496 if (enable_ns) 497 printf("\n NS is now on! \n"); 498 else 499 printf("\n NS is now off! \n"); 500 } else if (option_selection == option_index++) { 501 experimental_ns_enabled = !experimental_ns_enabled; 502 Config config; 503 config.Set<ExperimentalNs>(new ExperimentalNs(experimental_ns_enabled)); 504 base1->audio_processing()->SetExtraOptions(config); 505 if (experimental_ns_enabled) { 506 printf("\n Experimental NS is now on!\n"); 507 } else { 508 printf("\n Experimental NS is now off!\n"); 509 } 510 } else if (option_selection == option_index++) { 511 enable_aec = !enable_aec; 512 res = apm->SetEcStatus(enable_aec, kEcUnchanged); 513 VALIDATE; 514 if (enable_aec) 515 printf("\n Echo control is now on! \n"); 516 else 517 printf("\n Echo control is now off! \n"); 518 } else if (option_selection == option_index++) { 519 res = apm->SetEcStatus(enable_aec, kEcAec); 520 VALIDATE; 521 printf("\n AEC selected! \n"); 522 if (enable_aec) 523 printf(" (Echo control is on)\n"); 524 else 525 printf(" (Echo control is off)\n"); 526 } else if (option_selection == option_index++) { 527 res = apm->SetEcStatus(enable_aec, kEcAecm); 528 VALIDATE; 529 printf("\n AECM selected! \n"); 530 if (enable_aec) 531 printf(" (Echo control is on)\n"); 532 else 533 printf(" (Echo control is off)\n"); 534 } else if (option_selection == option_index++) { 535 unsigned vol(0); 536 res = volume->GetSpeakerVolume(vol); 537 VALIDATE; 538 printf("\n Speaker Volume is %d \n", vol); 539 } else if (option_selection == option_index++) { 540 printf("Level: "); 541 int level; 542 ASSERT_EQ(1, scanf("%i", &level)); 543 res = volume->SetSpeakerVolume(level); 544 VALIDATE; 545 } else if (option_selection == option_index++) { 546 unsigned vol(0); 547 res = volume->GetMicVolume(vol); 548 VALIDATE; 549 printf("\n Microphone Volume is %d \n", vol); 550 } else if (option_selection == option_index++) { 551 printf("Level: "); 552 int level; 553 ASSERT_EQ(1, scanf("%i", &level)); 554 res = volume->SetMicVolume(level); 555 VALIDATE; 556 } else if (option_selection == option_index++) { 557 res = file->StartPlayingFileLocally(0, audio_filename.c_str()); 558 VALIDATE; 559 } else if (option_selection == option_index++) { 560 // change the playout device with current call 561 int num_pd(-1); 562 res = hardware->GetNumOfPlayoutDevices(num_pd); 563 VALIDATE; 564 565 char dn[128] = { 0 }; 566 char guid[128] = { 0 }; 567 568 printf("\nPlayout devices (%d): \n", num_pd); 569 for (int i = 0; i < num_pd; ++i) { 570 res = hardware->GetPlayoutDeviceName(i, dn, guid); 571 VALIDATE; 572 printf(" %d: %s \n", i, dn); 573 } 574 printf("Select playout device: "); 575 ASSERT_EQ(1, scanf("%d", &num_pd)); 576 // Will use plughw for hardware devices 577 res = hardware->SetPlayoutDevice(num_pd); 578 VALIDATE; 579 } else if (option_selection == option_index++) { 580 // change the recording device with current call 581 int num_rd(-1); 582 583 res = hardware->GetNumOfRecordingDevices(num_rd); 584 VALIDATE; 585 586 char dn[128] = { 0 }; 587 char guid[128] = { 0 }; 588 589 printf("Recording devices (%d): \n", num_rd); 590 for (int i = 0; i < num_rd; ++i) { 591 res = hardware->GetRecordingDeviceName(i, dn, guid); 592 VALIDATE; 593 printf(" %d: %s \n", i, dn); 594 } 595 596 printf("Select recording device: "); 597 ASSERT_EQ(1, scanf("%d", &num_rd)); 598 printf("Setting sound devices \n"); 599 // Will use plughw for hardware devices 600 res = hardware->SetRecordingDevice(num_rd); 601 VALIDATE; 602 } else if (option_selection == option_index++) { 603 // Remote AGC 604 enable_rx_agc = !enable_rx_agc; 605 res = apm->SetRxAgcStatus(chan, enable_rx_agc); 606 VALIDATE; 607 if (enable_rx_agc) 608 printf("\n Receive-side AGC is now on! \n"); 609 else 610 printf("\n Receive-side AGC is now off! \n"); 611 } else if (option_selection == option_index++) { 612 // Remote NS 613 enable_rx_ns = !enable_rx_ns; 614 res = apm->SetRxNsStatus(chan, enable_rx_ns); 615 VALIDATE; 616 if (enable_rx_ns) 617 printf("\n Receive-side NS is now on! \n"); 618 else 619 printf("\n Receive-side NS is now off! \n"); 620 } else if (option_selection == option_index++) { 621 AgcModes agcmode; 622 bool enable; 623 res = apm->GetAgcStatus(enable, agcmode); 624 VALIDATE 625 printf("\n AGC enable is %d, mode is %d \n", enable, agcmode); 626 } else if (option_selection == option_index++) { 627 // Toggle Mute on Microphone 628 res = volume->GetInputMute(chan, muted); 629 VALIDATE; 630 muted = !muted; 631 res = volume->SetInputMute(chan, muted); 632 VALIDATE; 633 if (muted) 634 printf("\n Microphone is now on mute! \n"); 635 else 636 printf("\n Microphone is no longer on mute! \n"); 637 } else if (option_selection == option_index++) { 638 // Get the last error code and print to screen 639 int err_code = 0; 640 err_code = base1->LastError(); 641 if (err_code != -1) 642 printf("\n The last error code was %i.\n", err_code); 643 } else if (option_selection == option_index++) { 644 typing_detection= !typing_detection; 645 res = apm->SetTypingDetectionStatus(typing_detection); 646 VALIDATE; 647 if (typing_detection) 648 printf("\n Typing detection is now on!\n"); 649 else 650 printf("\n Typing detection is now off!\n"); 651 } else if (option_selection == option_index++) { 652 int stop_record = 1; 653 int file_source = 1; 654 printf("\n Select source of recorded file. "); 655 printf("\n 1. Record from microphone to file "); 656 printf("\n 2. Record from playout to file "); 657 printf("\n Enter your selection: \n"); 658 ASSERT_EQ(1, scanf("%i", &file_source)); 659 if (file_source == 1) { 660 printf("\n Start recording microphone as %s \n", 661 mic_filename.c_str()); 662 res = file->StartRecordingMicrophone(mic_filename.c_str()); 663 VALIDATE; 664 } else { 665 printf("\n Start recording playout as %s \n", play_filename.c_str()); 666 res = file->StartRecordingPlayout(chan, play_filename.c_str()); 667 VALIDATE; 668 } 669 while (stop_record != 0) { 670 printf("\n Type 0 to stop recording file \n"); 671 ASSERT_EQ(1, scanf("%i", &stop_record)); 672 } 673 if (file_source == 1) { 674 res = file->StopRecordingMicrophone(); 675 VALIDATE; 676 } else { 677 res = file->StopRecordingPlayout(chan); 678 VALIDATE; 679 } 680 printf("\n File finished recording \n"); 681 } else if (option_selection == option_index++) { 682 int file_type = 1; 683 int stop_play = 1; 684 printf("\n Select a file to play locally in a loop."); 685 printf("\n 1. Play %s", mic_filename.c_str()); 686 printf("\n 2. Play %s", play_filename.c_str()); 687 printf("\n Enter your selection\n"); 688 ASSERT_EQ(1, scanf("%i", &file_type)); 689 if (file_type == 1) { 690 printf("\n Start playing %s locally in a loop\n", 691 mic_filename.c_str()); 692 res = file->StartPlayingFileLocally(chan, mic_filename.c_str(), true); 693 VALIDATE; 694 } else { 695 printf("\n Start playing %s locally in a loop\n", 696 play_filename.c_str()); 697 res = file->StartPlayingFileLocally(chan, play_filename.c_str(), 698 true); 699 VALIDATE; 700 } 701 while (stop_play != 0) { 702 printf("\n Type 0 to stop playing file\n"); 703 ASSERT_EQ(1, scanf("%i", &stop_play)); 704 } 705 res = file->StopPlayingFileLocally(chan); 706 VALIDATE; 707 } else if (option_selection == option_index++) { 708 int file_type = 1; 709 int stop_play = 1; 710 printf("\n Select a file to play as microphone in a loop."); 711 printf("\n 1. Play %s", mic_filename.c_str()); 712 printf("\n 2. Play %s", play_filename.c_str()); 713 printf("\n Enter your selection\n"); 714 ASSERT_EQ(1, scanf("%i", &file_type)); 715 if (file_type == 1) { 716 printf("\n Start playing %s as mic in a loop\n", 717 mic_filename.c_str()); 718 res = file->StartPlayingFileAsMicrophone(chan, mic_filename.c_str(), 719 true); 720 VALIDATE; 721 } else { 722 printf("\n Start playing %s as mic in a loop\n", 723 play_filename.c_str()); 724 res = file->StartPlayingFileAsMicrophone(chan, play_filename.c_str(), 725 true); 726 VALIDATE; 727 } 728 while (stop_play != 0) { 729 printf("\n Type 0 to stop playing file\n"); 730 ASSERT_EQ(1, scanf("%i", &stop_play)); 731 } 732 res = file->StopPlayingFileAsMicrophone(chan); 733 VALIDATE; 734 } else if (option_selection == option_index++) { 735 if (channel_index < kMaxNumChannels) { 736 res = base1->StartReceive(channels[channel_index]); 737 VALIDATE; 738 res = base1->StartPlayout(channels[channel_index]); 739 VALIDATE; 740 res = base1->StartSend(channels[channel_index]); 741 VALIDATE; 742 res = file->StartPlayingFileAsMicrophone(channels[channel_index], 743 audio_filename.c_str(), 744 true, 745 false); 746 VALIDATE; 747 channel_index++; 748 printf("Using %d additional channels\n", channel_index); 749 } else { 750 printf("Max number of channels reached\n"); 751 } 752 } else if (option_selection == option_index++) { 753 if (channel_index > 0) { 754 channel_index--; 755 res = file->StopPlayingFileAsMicrophone(channels[channel_index]); 756 VALIDATE; 757 res = base1->StopSend(channels[channel_index]); 758 VALIDATE; 759 res = base1->StopPlayout(channels[channel_index]); 760 VALIDATE; 761 res = base1->StopReceive(channels[channel_index]); 762 VALIDATE; 763 printf("Using %d additional channels\n", channel_index); 764 } else { 765 printf("All additional channels stopped\n"); 766 } 767 } else if (option_selection == option_index++) { 768 opus_stereo = !opus_stereo; 769 if (opus_stereo) 770 printf("\n Opus stereo enabled (select Opus again to apply the " 771 "setting). \n"); 772 else 773 printf("\n Opus mono enabled (select Opus again to apply the " 774 "setting). \n"); 775 } else if (option_selection == option_index++) { 776 printf("\n Input maxium playback rate in Hz: "); 777 int max_playback_rate; 778 ASSERT_EQ(1, scanf("%i", &max_playback_rate)); 779 res = codec->SetOpusMaxPlaybackRate(chan, max_playback_rate); 780 VALIDATE; 781 } else if (option_selection == option_index++) { 782 opus_dtx = !opus_dtx; 783 res = codec->SetOpusDtx(chan, opus_dtx); 784 VALIDATE; 785 printf("Opus DTX %s.\n", opus_dtx ? "enabled" : "disabled"); 786 } else if (option_selection == option_index++) { 787 res = codec->GetSendCodec(chan, cinst); 788 VALIDATE; 789 printf("Current bit rate is %i bps, set to: ", cinst.rate); 790 int new_bitrate_bps; 791 ASSERT_EQ(1, scanf("%i", &new_bitrate_bps)); 792 res = codec->SetBitRate(chan, new_bitrate_bps); 793 VALIDATE; 794 } else if (option_selection == option_index++) { 795 const char* kDebugFileName = "audio.aecdump"; 796 if (debug_recording_started) { 797 apm->StopDebugRecording(); 798 printf("Debug recording named %s stopped\n", kDebugFileName); 799 } else { 800 apm->StartDebugRecording(kDebugFileName); 801 printf("Debug recording named %s started\n", kDebugFileName); 802 } 803 debug_recording_started = !debug_recording_started; 804 } else if (option_selection == option_index++) { 805 const char* kDebugFileName = "eventlog.rel"; 806 codec->GetEventLog()->StartLogging(kDebugFileName, 30000); 807 } else { 808 break; 809 } 810 } 811 812 if (debug_recording_started) { 813 apm->StopDebugRecording(); 814 } 815 816 if (send) { 817 printf("Stop Send \n"); 818 res = base1->StopSend(chan); 819 VALIDATE; 820 } 821 822 if (receive) { 823 printf("Stop Playout \n"); 824 res = base1->StopPlayout(chan); 825 VALIDATE; 826 827 #ifndef EXTERNAL_TRANSPORT 828 printf("Stop Listen \n"); 829 res = base1->StopReceive(chan); 830 VALIDATE; 831 #endif 832 } 833 834 while (channel_index > 0) { 835 --channel_index; 836 res = file->StopPlayingFileAsMicrophone(channels[channel_index]); 837 VALIDATE; 838 res = base1->StopSend(channels[channel_index]); 839 VALIDATE; 840 res = base1->StopPlayout(channels[channel_index]); 841 VALIDATE; 842 res = base1->StopReceive(channels[channel_index]); 843 VALIDATE; 844 } 845 846 printf("\n1. New call \n"); 847 printf("2. Quit \n"); 848 printf("Select action: "); 849 int end_option; 850 ASSERT_EQ(1, scanf("%i", &end_option)); 851 newcall = (end_option == 1); 852 // Call loop 853 } 854 855 // Transports should be deleted before channel deletion. 856 delete voice_channel_transport; 857 for (int i = 0; i < kMaxNumChannels; ++i) { 858 delete voice_channel_transports[i]; 859 voice_channel_transports[i] = NULL; 860 } 861 862 printf("Delete channels \n"); 863 res = base1->DeleteChannel(chan); 864 VALIDATE; 865 866 for (int i = 0; i < kMaxNumChannels; ++i) { 867 res = base1->DeleteChannel(channels[i]); 868 VALIDATE; 869 } 870 } 871