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. Get last error code \n", option_index++); 437 printf("%i. Toggle typing detection \n", 438 option_index++); 439 printf("%i. Record a PCM file \n", option_index++); 440 printf("%i. Play a previously recorded PCM file locally \n", 441 option_index++); 442 printf("%i. Play a previously recorded PCM file as microphone \n", 443 option_index++); 444 printf("%i. Add an additional file-playing channel \n", option_index++); 445 printf("%i. Remove a file-playing channel \n", option_index++); 446 printf("%i. Toggle Opus stereo (Opus must be selected again to apply " 447 "the setting) \n", option_index++); 448 printf("%i. Set Opus maximum playback rate \n", option_index++); 449 printf("%i. Set bit rate (only take effect on codecs that allow the " 450 "change) \n", option_index++); 451 452 printf("Select action or %i to stop the call: ", option_index); 453 int option_selection; 454 ASSERT_EQ(1, scanf("%i", &option_selection)); 455 456 option_index = num_codecs; 457 if (option_selection < option_index) { 458 res = codec->GetCodec(option_selection, cinst); 459 VALIDATE; 460 SetStereoIfOpus(opus_stereo, &cinst); 461 printf("Set primary codec\n"); 462 res = codec->SetSendCodec(chan, cinst); 463 VALIDATE; 464 } else if (option_selection == option_index++) { 465 enable_cng = !enable_cng; 466 res = codec->SetVADStatus(0, enable_cng); 467 VALIDATE; 468 if (enable_cng) 469 printf("\n CNG is now on! \n"); 470 else 471 printf("\n CNG is now off! \n"); 472 } else if (option_selection == option_index++) { 473 enable_agc = !enable_agc; 474 res = apm->SetAgcStatus(enable_agc); 475 VALIDATE; 476 if (enable_agc) 477 printf("\n AGC is now on! \n"); 478 else 479 printf("\n AGC is now off! \n"); 480 } else if (option_selection == option_index++) { 481 enable_ns = !enable_ns; 482 res = apm->SetNsStatus(enable_ns); 483 VALIDATE; 484 if (enable_ns) 485 printf("\n NS is now on! \n"); 486 else 487 printf("\n NS is now off! \n"); 488 } else if (option_selection == option_index++) { 489 experimental_ns_enabled = !experimental_ns_enabled; 490 Config config; 491 config.Set<ExperimentalNs>(new ExperimentalNs(experimental_ns_enabled)); 492 base1->audio_processing()->SetExtraOptions(config); 493 if (experimental_ns_enabled) { 494 printf("\n Experimental NS is now on!\n"); 495 } else { 496 printf("\n Experimental NS is now off!\n"); 497 } 498 } else if (option_selection == option_index++) { 499 enable_aec = !enable_aec; 500 res = apm->SetEcStatus(enable_aec, kEcUnchanged); 501 VALIDATE; 502 if (enable_aec) 503 printf("\n Echo control is now on! \n"); 504 else 505 printf("\n Echo control is now off! \n"); 506 } else if (option_selection == option_index++) { 507 res = apm->SetEcStatus(enable_aec, kEcAec); 508 VALIDATE; 509 printf("\n AEC selected! \n"); 510 if (enable_aec) 511 printf(" (Echo control is on)\n"); 512 else 513 printf(" (Echo control is off)\n"); 514 } else if (option_selection == option_index++) { 515 res = apm->SetEcStatus(enable_aec, kEcAecm); 516 VALIDATE; 517 printf("\n AECM selected! \n"); 518 if (enable_aec) 519 printf(" (Echo control is on)\n"); 520 else 521 printf(" (Echo control is off)\n"); 522 } else if (option_selection == option_index++) { 523 unsigned vol(0); 524 res = volume->GetSpeakerVolume(vol); 525 VALIDATE; 526 printf("\n Speaker Volume is %d \n", vol); 527 } else if (option_selection == option_index++) { 528 printf("Level: "); 529 int level; 530 ASSERT_EQ(1, scanf("%i", &level)); 531 res = volume->SetSpeakerVolume(level); 532 VALIDATE; 533 } else if (option_selection == option_index++) { 534 unsigned vol(0); 535 res = volume->GetMicVolume(vol); 536 VALIDATE; 537 printf("\n Microphone Volume is %d \n", vol); 538 } else if (option_selection == option_index++) { 539 printf("Level: "); 540 int level; 541 ASSERT_EQ(1, scanf("%i", &level)); 542 res = volume->SetMicVolume(level); 543 VALIDATE; 544 } else if (option_selection == option_index++) { 545 res = file->StartPlayingFileLocally(0, audio_filename.c_str()); 546 VALIDATE; 547 } else if (option_selection == option_index++) { 548 // change the playout device with current call 549 int num_pd(-1); 550 res = hardware->GetNumOfPlayoutDevices(num_pd); 551 VALIDATE; 552 553 char dn[128] = { 0 }; 554 char guid[128] = { 0 }; 555 556 printf("\nPlayout devices (%d): \n", num_pd); 557 for (int i = 0; i < num_pd; ++i) { 558 res = hardware->GetPlayoutDeviceName(i, dn, guid); 559 VALIDATE; 560 printf(" %d: %s \n", i, dn); 561 } 562 printf("Select playout device: "); 563 ASSERT_EQ(1, scanf("%d", &num_pd)); 564 // Will use plughw for hardware devices 565 res = hardware->SetPlayoutDevice(num_pd); 566 VALIDATE; 567 } else if (option_selection == option_index++) { 568 // change the recording device with current call 569 int num_rd(-1); 570 571 res = hardware->GetNumOfRecordingDevices(num_rd); 572 VALIDATE; 573 574 char dn[128] = { 0 }; 575 char guid[128] = { 0 }; 576 577 printf("Recording devices (%d): \n", num_rd); 578 for (int i = 0; i < num_rd; ++i) { 579 res = hardware->GetRecordingDeviceName(i, dn, guid); 580 VALIDATE; 581 printf(" %d: %s \n", i, dn); 582 } 583 584 printf("Select recording device: "); 585 ASSERT_EQ(1, scanf("%d", &num_rd)); 586 printf("Setting sound devices \n"); 587 // Will use plughw for hardware devices 588 res = hardware->SetRecordingDevice(num_rd); 589 VALIDATE; 590 } else if (option_selection == option_index++) { 591 // Remote AGC 592 enable_rx_agc = !enable_rx_agc; 593 res = apm->SetRxAgcStatus(chan, enable_rx_agc); 594 VALIDATE; 595 if (enable_rx_agc) 596 printf("\n Receive-side AGC is now on! \n"); 597 else 598 printf("\n Receive-side AGC is now off! \n"); 599 } else if (option_selection == option_index++) { 600 // Remote NS 601 enable_rx_ns = !enable_rx_ns; 602 res = apm->SetRxNsStatus(chan, enable_rx_ns); 603 VALIDATE; 604 if (enable_rx_ns) 605 printf("\n Receive-side NS is now on! \n"); 606 else 607 printf("\n Receive-side NS is now off! \n"); 608 } else if (option_selection == option_index++) { 609 AgcModes agcmode; 610 bool enable; 611 res = apm->GetAgcStatus(enable, agcmode); 612 VALIDATE 613 printf("\n AGC enable is %d, mode is %d \n", enable, agcmode); 614 } else if (option_selection == option_index++) { 615 // Toggle Mute on Microphone 616 res = volume->GetInputMute(chan, muted); 617 VALIDATE; 618 muted = !muted; 619 res = volume->SetInputMute(chan, muted); 620 VALIDATE; 621 if (muted) 622 printf("\n Microphone is now on mute! \n"); 623 else 624 printf("\n Microphone is no longer on mute! \n"); 625 } else if (option_selection == option_index++) { 626 // Get the last error code and print to screen 627 int err_code = 0; 628 err_code = base1->LastError(); 629 if (err_code != -1) 630 printf("\n The last error code was %i.\n", err_code); 631 } else if (option_selection == option_index++) { 632 typing_detection= !typing_detection; 633 res = apm->SetTypingDetectionStatus(typing_detection); 634 VALIDATE; 635 if (typing_detection) 636 printf("\n Typing detection is now on!\n"); 637 else 638 printf("\n Typing detection is now off!\n"); 639 } else if (option_selection == option_index++) { 640 int stop_record = 1; 641 int file_source = 1; 642 printf("\n Select source of recorded file. "); 643 printf("\n 1. Record from microphone to file "); 644 printf("\n 2. Record from playout to file "); 645 printf("\n Enter your selection: \n"); 646 ASSERT_EQ(1, scanf("%i", &file_source)); 647 if (file_source == 1) { 648 printf("\n Start recording microphone as %s \n", 649 mic_filename.c_str()); 650 res = file->StartRecordingMicrophone(mic_filename.c_str()); 651 VALIDATE; 652 } else { 653 printf("\n Start recording playout as %s \n", play_filename.c_str()); 654 res = file->StartRecordingPlayout(chan, play_filename.c_str()); 655 VALIDATE; 656 } 657 while (stop_record != 0) { 658 printf("\n Type 0 to stop recording file \n"); 659 ASSERT_EQ(1, scanf("%i", &stop_record)); 660 } 661 if (file_source == 1) { 662 res = file->StopRecordingMicrophone(); 663 VALIDATE; 664 } else { 665 res = file->StopRecordingPlayout(chan); 666 VALIDATE; 667 } 668 printf("\n File finished recording \n"); 669 } else if (option_selection == option_index++) { 670 int file_type = 1; 671 int stop_play = 1; 672 printf("\n Select a file to play locally in a loop."); 673 printf("\n 1. Play %s", mic_filename.c_str()); 674 printf("\n 2. Play %s", play_filename.c_str()); 675 printf("\n Enter your selection\n"); 676 ASSERT_EQ(1, scanf("%i", &file_type)); 677 if (file_type == 1) { 678 printf("\n Start playing %s locally in a loop\n", 679 mic_filename.c_str()); 680 res = file->StartPlayingFileLocally(chan, mic_filename.c_str(), true); 681 VALIDATE; 682 } else { 683 printf("\n Start playing %s locally in a loop\n", 684 play_filename.c_str()); 685 res = file->StartPlayingFileLocally(chan, play_filename.c_str(), 686 true); 687 VALIDATE; 688 } 689 while (stop_play != 0) { 690 printf("\n Type 0 to stop playing file\n"); 691 ASSERT_EQ(1, scanf("%i", &stop_play)); 692 } 693 res = file->StopPlayingFileLocally(chan); 694 VALIDATE; 695 } else if (option_selection == option_index++) { 696 int file_type = 1; 697 int stop_play = 1; 698 printf("\n Select a file to play as microphone in a loop."); 699 printf("\n 1. Play %s", mic_filename.c_str()); 700 printf("\n 2. Play %s", play_filename.c_str()); 701 printf("\n Enter your selection\n"); 702 ASSERT_EQ(1, scanf("%i", &file_type)); 703 if (file_type == 1) { 704 printf("\n Start playing %s as mic in a loop\n", 705 mic_filename.c_str()); 706 res = file->StartPlayingFileAsMicrophone(chan, mic_filename.c_str(), 707 true); 708 VALIDATE; 709 } else { 710 printf("\n Start playing %s as mic in a loop\n", 711 play_filename.c_str()); 712 res = file->StartPlayingFileAsMicrophone(chan, play_filename.c_str(), 713 true); 714 VALIDATE; 715 } 716 while (stop_play != 0) { 717 printf("\n Type 0 to stop playing file\n"); 718 ASSERT_EQ(1, scanf("%i", &stop_play)); 719 } 720 res = file->StopPlayingFileAsMicrophone(chan); 721 VALIDATE; 722 } else if (option_selection == option_index++) { 723 if (channel_index < kMaxNumChannels) { 724 res = base1->StartReceive(channels[channel_index]); 725 VALIDATE; 726 res = base1->StartPlayout(channels[channel_index]); 727 VALIDATE; 728 res = base1->StartSend(channels[channel_index]); 729 VALIDATE; 730 res = file->StartPlayingFileAsMicrophone(channels[channel_index], 731 audio_filename.c_str(), 732 true, 733 false); 734 VALIDATE; 735 channel_index++; 736 printf("Using %d additional channels\n", channel_index); 737 } else { 738 printf("Max number of channels reached\n"); 739 } 740 } else if (option_selection == option_index++) { 741 if (channel_index > 0) { 742 channel_index--; 743 res = file->StopPlayingFileAsMicrophone(channels[channel_index]); 744 VALIDATE; 745 res = base1->StopSend(channels[channel_index]); 746 VALIDATE; 747 res = base1->StopPlayout(channels[channel_index]); 748 VALIDATE; 749 res = base1->StopReceive(channels[channel_index]); 750 VALIDATE; 751 printf("Using %d additional channels\n", channel_index); 752 } else { 753 printf("All additional channels stopped\n"); 754 } 755 } else if (option_selection == option_index++) { 756 opus_stereo = !opus_stereo; 757 if (opus_stereo) 758 printf("\n Opus stereo enabled (select Opus again to apply the " 759 "setting). \n"); 760 else 761 printf("\n Opus mono enabled (select Opus again to apply the " 762 "setting). \n"); 763 } else if (option_selection == option_index++) { 764 printf("\n Input maxium playback rate in Hz: "); 765 int max_playback_rate; 766 ASSERT_EQ(1, scanf("%i", &max_playback_rate)); 767 res = codec->SetOpusMaxPlaybackRate(chan, max_playback_rate); 768 VALIDATE; 769 } else if (option_selection == option_index++) { 770 res = codec->GetSendCodec(chan, cinst); 771 VALIDATE; 772 printf("Current bit rate is %i bps, set to: ", cinst.rate); 773 ASSERT_EQ(1, scanf("%i", &cinst.rate)); 774 res = codec->SetSendCodec(chan, cinst); 775 VALIDATE; 776 } else { 777 break; 778 } 779 } 780 781 if (send) { 782 printf("Stop Send \n"); 783 res = base1->StopSend(chan); 784 VALIDATE; 785 } 786 787 if (receive) { 788 printf("Stop Playout \n"); 789 res = base1->StopPlayout(chan); 790 VALIDATE; 791 792 #ifndef EXTERNAL_TRANSPORT 793 printf("Stop Listen \n"); 794 res = base1->StopReceive(chan); 795 VALIDATE; 796 #endif 797 } 798 799 while (channel_index > 0) { 800 --channel_index; 801 res = file->StopPlayingFileAsMicrophone(channels[channel_index]); 802 VALIDATE; 803 res = base1->StopSend(channels[channel_index]); 804 VALIDATE; 805 res = base1->StopPlayout(channels[channel_index]); 806 VALIDATE; 807 res = base1->StopReceive(channels[channel_index]); 808 VALIDATE; 809 } 810 811 printf("\n1. New call \n"); 812 printf("2. Quit \n"); 813 printf("Select action: "); 814 int end_option; 815 ASSERT_EQ(1, scanf("%i", &end_option)); 816 newcall = (end_option == 1); 817 // Call loop 818 } 819 for (int i = 0; i < kMaxNumChannels; ++i) { 820 delete voice_channel_transports[i]; 821 voice_channel_transports[i] = NULL; 822 } 823 824 printf("Delete channels \n"); 825 res = base1->DeleteChannel(chan); 826 VALIDATE; 827 828 for (int i = 0; i < kMaxNumChannels; ++i) { 829 channels[i] = base1->DeleteChannel(channels[i]); 830 VALIDATE; 831 } 832 } 833