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