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