aboutsummaryrefslogtreecommitdiff
path: root/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc
diff options
context:
space:
mode:
authorChih-hung Hsieh <chh@google.com>2015-12-01 17:07:48 +0000
committerandroid-build-merger <android-build-merger@google.com>2015-12-01 17:07:48 +0000
commita4acd9d6bc9b3b033d7d274316e75ee067df8d20 (patch)
tree672a185b294789cf991f385c3e395dd63bea9063 /webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc
parent3681b90ba4fe7a27232dd3e27897d5d7ed9d651c (diff)
parentfe8b4a657979b49e1701bd92f6d5814a99e0b2be (diff)
downloadwebrtc-a4acd9d6bc9b3b033d7d274316e75ee067df8d20.tar.gz
Merge changes I7bbf776e,I1b827825
am: fe8b4a6579 * commit 'fe8b4a657979b49e1701bd92f6d5814a99e0b2be': (7237 commits) WIP: Changes after merge commit 'cb3f9bd' Make the nonlinear beamformer steerable Utilize bitrate above codec max to protect video. Enable VP9 internal resize by default. Filter overlapping RTP header extensions. Make VCMEncodedFrameCallback const. MediaCodecVideoEncoder: Add number of quality resolution downscales to Encoded callback. Remove redudant encoder rate calls. Create isolate files for nonparallel tests. Register header extensions in RtpRtcpObserver to avoid log spam. Make an enum class out of NetEqDecoder, and hide the neteq_decoders_ table ACM: Move NACK functionality inside NetEq Fix chromium-style warnings in webrtc/sound/. Create a 'webrtc_nonparallel_tests' target. Update scalability structure data according to updates in the RTP payload profile. audio_coding: rename interface -> include Rewrote perform_action_on_all_files to be parallell. Update reference indices according to updates in the RTP payload profile. Disable P2PTransport...TestFailoverControlledSide on Memcheck pass clangcl compile options to ignore warnings in gflags.cc ...
Diffstat (limited to 'webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc')
-rw-r--r--webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc869
1 files changed, 869 insertions, 0 deletions
diff --git a/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc b/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc
new file mode 100644
index 0000000000..312ac7ca31
--- /dev/null
+++ b/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc
@@ -0,0 +1,869 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#include <vector>
+
+#include "gflags/gflags.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/call/rtc_event_log.h"
+#include "webrtc/engine_configurations.h"
+#include "webrtc/modules/audio_processing/include/audio_processing.h"
+#include "webrtc/test/channel_transport/include/channel_transport.h"
+#include "webrtc/test/testsupport/fileutils.h"
+#include "webrtc/test/testsupport/trace_to_stderr.h"
+#include "webrtc/voice_engine/include/voe_audio_processing.h"
+#include "webrtc/voice_engine/include/voe_base.h"
+#include "webrtc/voice_engine/include/voe_codec.h"
+#include "webrtc/voice_engine/include/voe_dtmf.h"
+#include "webrtc/voice_engine/include/voe_errors.h"
+#include "webrtc/voice_engine/include/voe_external_media.h"
+#include "webrtc/voice_engine/include/voe_file.h"
+#include "webrtc/voice_engine/include/voe_hardware.h"
+#include "webrtc/voice_engine/include/voe_neteq_stats.h"
+#include "webrtc/voice_engine/include/voe_network.h"
+#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
+#include "webrtc/voice_engine/include/voe_video_sync.h"
+#include "webrtc/voice_engine/include/voe_volume_control.h"
+
+DEFINE_bool(use_log_file, false,
+ "Output logs to a file; by default they will be printed to stderr.");
+
+using namespace webrtc;
+using namespace test;
+
+#define VALIDATE \
+ if (res != 0) { \
+ printf("*** Error at line %i \n", __LINE__); \
+ printf("*** Error code = %i \n", base1->LastError()); \
+ }
+
+VoiceEngine* m_voe = NULL;
+VoEBase* base1 = NULL;
+VoECodec* codec = NULL;
+VoEVolumeControl* volume = NULL;
+VoEDtmf* dtmf = NULL;
+VoERTP_RTCP* rtp_rtcp = NULL;
+VoEAudioProcessing* apm = NULL;
+VoENetwork* netw = NULL;
+VoEFile* file = NULL;
+VoEVideoSync* vsync = NULL;
+VoEHardware* hardware = NULL;
+VoEExternalMedia* xmedia = NULL;
+VoENetEqStats* neteqst = NULL;
+
+void RunTest(std::string out_path);
+
+class MyObserver : public VoiceEngineObserver {
+ public:
+ virtual void CallbackOnError(int channel, int err_code);
+};
+
+void MyObserver::CallbackOnError(int channel, int err_code) {
+ // Add printf for other error codes here
+ if (err_code == VE_TYPING_NOISE_WARNING) {
+ printf(" TYPING NOISE DETECTED \n");
+ } else if (err_code == VE_TYPING_NOISE_OFF_WARNING) {
+ printf(" TYPING NOISE OFF DETECTED \n");
+ } else if (err_code == VE_RECEIVE_PACKET_TIMEOUT) {
+ printf(" RECEIVE PACKET TIMEOUT \n");
+ } else if (err_code == VE_PACKET_RECEIPT_RESTARTED) {
+ printf(" PACKET RECEIPT RESTARTED \n");
+ } else if (err_code == VE_RUNTIME_PLAY_WARNING) {
+ printf(" RUNTIME PLAY WARNING \n");
+ } else if (err_code == VE_RUNTIME_REC_WARNING) {
+ printf(" RUNTIME RECORD WARNING \n");
+ } else if (err_code == VE_SATURATION_WARNING) {
+ printf(" SATURATION WARNING \n");
+ } else if (err_code == VE_RUNTIME_PLAY_ERROR) {
+ printf(" RUNTIME PLAY ERROR \n");
+ } else if (err_code == VE_RUNTIME_REC_ERROR) {
+ printf(" RUNTIME RECORD ERROR \n");
+ } else if (err_code == VE_REC_DEVICE_REMOVED) {
+ printf(" RECORD DEVICE REMOVED \n");
+ }
+}
+
+void SetStereoIfOpus(bool use_stereo, CodecInst* codec_params) {
+ if (strncmp(codec_params->plname, "opus", 4) == 0) {
+ if (use_stereo)
+ codec_params->channels = 2;
+ else
+ codec_params->channels = 1;
+ }
+}
+
+void PrintCodecs(bool opus_stereo) {
+ CodecInst codec_params;
+ for (int i = 0; i < codec->NumOfCodecs(); ++i) {
+ int res = codec->GetCodec(i, codec_params);
+ VALIDATE;
+ SetStereoIfOpus(opus_stereo, &codec_params);
+ printf("%2d. %3d %s/%d/%d \n", i, codec_params.pltype, codec_params.plname,
+ codec_params.plfreq, codec_params.channels);
+ }
+}
+
+int main(int argc, char** argv) {
+ google::ParseCommandLineFlags(&argc, &argv, true);
+
+ int res = 0;
+
+ printf("Test started \n");
+
+ m_voe = VoiceEngine::Create();
+ base1 = VoEBase::GetInterface(m_voe);
+ codec = VoECodec::GetInterface(m_voe);
+ apm = VoEAudioProcessing::GetInterface(m_voe);
+ volume = VoEVolumeControl::GetInterface(m_voe);
+ dtmf = VoEDtmf::GetInterface(m_voe);
+ rtp_rtcp = VoERTP_RTCP::GetInterface(m_voe);
+ netw = VoENetwork::GetInterface(m_voe);
+ file = VoEFile::GetInterface(m_voe);
+ vsync = VoEVideoSync::GetInterface(m_voe);
+ hardware = VoEHardware::GetInterface(m_voe);
+ xmedia = VoEExternalMedia::GetInterface(m_voe);
+ neteqst = VoENetEqStats::GetInterface(m_voe);
+
+ MyObserver my_observer;
+
+ rtc::scoped_ptr<test::TraceToStderr> trace_to_stderr;
+ if (!FLAGS_use_log_file) {
+ trace_to_stderr.reset(new test::TraceToStderr);
+ } else {
+ const std::string trace_filename = test::OutputPath() + "webrtc_trace.txt";
+ VoiceEngine::SetTraceFilter(kTraceAll);
+ res = VoiceEngine::SetTraceFile(trace_filename.c_str());
+ VALIDATE;
+ res = VoiceEngine::SetTraceCallback(NULL);
+ VALIDATE;
+ printf("Outputting logs to file: %s\n", trace_filename.c_str());
+ }
+
+ printf("Init\n");
+ res = base1->Init();
+ if (res != 0) {
+ printf("\nError calling Init: %d\n", base1->LastError());
+ fflush(NULL);
+ exit(1);
+ }
+
+ res = base1->RegisterVoiceEngineObserver(my_observer);
+ VALIDATE;
+
+ printf("Version\n");
+ char tmp[1024];
+ res = base1->GetVersion(tmp);
+ VALIDATE;
+ printf("%s\n", tmp);
+
+ RunTest(test::OutputPath());
+
+ printf("Terminate \n");
+
+ base1->DeRegisterVoiceEngineObserver();
+
+ res = base1->Terminate();
+ VALIDATE;
+
+ if (base1)
+ base1->Release();
+
+ if (codec)
+ codec->Release();
+
+ if (volume)
+ volume->Release();
+
+ if (dtmf)
+ dtmf->Release();
+
+ if (rtp_rtcp)
+ rtp_rtcp->Release();
+
+ if (apm)
+ apm->Release();
+
+ if (netw)
+ netw->Release();
+
+ if (file)
+ file->Release();
+
+ if (vsync)
+ vsync->Release();
+
+ if (hardware)
+ hardware->Release();
+
+ if (xmedia)
+ xmedia->Release();
+
+ if (neteqst)
+ neteqst->Release();
+
+ VoiceEngine::Delete(m_voe);
+
+ return 0;
+}
+
+void RunTest(std::string out_path) {
+ int chan, res;
+ CodecInst cinst;
+ bool enable_aec = false;
+ bool enable_agc = false;
+ bool enable_rx_agc = false;
+ bool enable_cng = false;
+ bool enable_ns = false;
+ bool enable_rx_ns = false;
+ bool typing_detection = false;
+ bool muted = false;
+ bool opus_stereo = false;
+ bool opus_dtx = false;
+ bool experimental_ns_enabled = false;
+ bool debug_recording_started = false;
+
+#if defined(WEBRTC_ANDROID)
+ std::string resource_path = "/sdcard/";
+#else
+ std::string resource_path = webrtc::test::ProjectRootPath();
+ if (resource_path == webrtc::test::kCannotFindProjectRootDir) {
+ printf("*** Unable to get project root directory. "
+ "File playing may fail. ***\n");
+ // Fall back to the current directory.
+ resource_path = "./";
+ } else {
+ resource_path += "data/voice_engine/";
+ }
+#endif
+ const std::string audio_filename = resource_path + "audio_long16.pcm";
+
+ const std::string play_filename = out_path + "recorded_playout.pcm";
+ const std::string mic_filename = out_path + "recorded_mic.pcm";
+
+ chan = base1->CreateChannel();
+ if (chan < 0) {
+ printf("************ Error code = %i\n", base1->LastError());
+ fflush(NULL);
+ }
+
+ VoiceChannelTransport* voice_channel_transport(
+ new VoiceChannelTransport(netw, chan));
+
+ char ip[64];
+ printf("1. 127.0.0.1 \n");
+ printf("2. Specify IP \n");
+ int ip_selection;
+ ASSERT_EQ(1, scanf("%i", &ip_selection));
+
+ if (ip_selection == 1) {
+ strcpy(ip, "127.0.0.1");
+ } else {
+ printf("Specify remote IP: ");
+ ASSERT_EQ(1, scanf("%s", ip));
+ }
+
+ int rPort;
+ printf("Specify remote port (1=1234): ");
+ ASSERT_EQ(1, scanf("%i", &rPort));
+ if (1 == rPort)
+ rPort = 1234;
+ printf("Set Send port \n");
+
+ printf("Set Send IP \n");
+ res = voice_channel_transport->SetSendDestination(ip, rPort);
+ VALIDATE;
+
+ int lPort;
+ printf("Specify local port (1=1234): ");
+ ASSERT_EQ(1, scanf("%i", &lPort));
+ if (1 == lPort)
+ lPort = 1234;
+ printf("Set Rec Port \n");
+
+ res = voice_channel_transport->SetLocalReceiver(lPort);
+ VALIDATE;
+
+ printf("\n");
+ PrintCodecs(opus_stereo);
+ printf("Select send codec: ");
+ int codec_selection;
+ ASSERT_EQ(1, scanf("%i", &codec_selection));
+ codec->GetCodec(codec_selection, cinst);
+
+ printf("Set primary codec\n");
+ SetStereoIfOpus(opus_stereo, &cinst);
+ res = codec->SetSendCodec(chan, cinst);
+ VALIDATE;
+
+ const int kMaxNumChannels = 8;
+ int channel_index = 0;
+ std::vector<int> channels(kMaxNumChannels);
+ std::vector<VoiceChannelTransport*> voice_channel_transports(kMaxNumChannels);
+
+ for (int i = 0; i < kMaxNumChannels; ++i) {
+ channels[i] = base1->CreateChannel();
+ int port = rPort + (i + 1) * 2;
+
+ voice_channel_transports[i] = new VoiceChannelTransport(netw, channels[i]);
+
+ res = voice_channel_transports[i]->SetSendDestination(ip, port);
+ VALIDATE;
+ res = voice_channel_transports[i]->SetLocalReceiver(port);
+ VALIDATE;
+ res = codec->SetSendCodec(channels[i], cinst);
+ VALIDATE;
+ }
+
+ // Call loop
+ bool newcall = true;
+ while (newcall) {
+ int rd(-1), pd(-1);
+ res = hardware->GetNumOfRecordingDevices(rd);
+ VALIDATE;
+ res = hardware->GetNumOfPlayoutDevices(pd);
+ VALIDATE;
+
+ char dn[128] = { 0 };
+ char guid[128] = { 0 };
+ printf("\nPlayout devices (%d): \n", pd);
+ for (int j = 0; j < pd; ++j) {
+ res = hardware->GetPlayoutDeviceName(j, dn, guid);
+ VALIDATE;
+ printf(" %d: %s \n", j, dn);
+ }
+
+ printf("Recording devices (%d): \n", rd);
+ for (int j = 0; j < rd; ++j) {
+ res = hardware->GetRecordingDeviceName(j, dn, guid);
+ VALIDATE;
+ printf(" %d: %s \n", j, dn);
+ }
+
+ printf("Select playout device: ");
+ ASSERT_EQ(1, scanf("%d", &pd));
+ res = hardware->SetPlayoutDevice(pd);
+ VALIDATE;
+ printf("Select recording device: ");
+ ASSERT_EQ(1, scanf("%d", &rd));
+ printf("Setting sound devices \n");
+ res = hardware->SetRecordingDevice(rd);
+ VALIDATE;
+
+ res = codec->SetVADStatus(0, enable_cng);
+ VALIDATE;
+
+ res = apm->SetAgcStatus(enable_agc);
+ VALIDATE;
+
+ res = apm->SetEcStatus(enable_aec);
+ VALIDATE;
+
+ res = apm->SetNsStatus(enable_ns);
+ VALIDATE;
+
+ printf("\n1. Send, listen and playout \n");
+ printf("2. Send only \n");
+ printf("3. Listen and playout only \n");
+ printf("Select transfer mode: ");
+ int call_selection;
+ ASSERT_EQ(1, scanf("%i", &call_selection));
+ const bool send = !(call_selection == 3);
+ const bool receive = !(call_selection == 2);
+
+ if (receive) {
+#ifndef EXTERNAL_TRANSPORT
+ printf("Start Listen \n");
+ res = base1->StartReceive(chan);
+ VALIDATE;
+#endif
+
+ printf("Start Playout \n");
+ res = base1->StartPlayout(chan);
+ VALIDATE;
+ }
+
+ if (send) {
+ printf("Start Send \n");
+ res = base1->StartSend(chan);
+ VALIDATE;
+ }
+
+ printf("Getting mic volume \n");
+ unsigned int vol = 999;
+ res = volume->GetMicVolume(vol);
+ VALIDATE;
+ if ((vol > 255) || (vol < 1)) {
+ printf("\n****ERROR in GetMicVolume");
+ }
+
+ int forever = 1;
+ while (forever) {
+ printf("\nSelect codec\n");
+ PrintCodecs(opus_stereo);
+ printf("\nOther actions\n");
+ const int num_codecs = codec->NumOfCodecs();
+ int option_index = num_codecs;
+ printf("%i. Toggle CNG\n", option_index++);
+ printf("%i. Toggle AGC\n", option_index++);
+ printf("%i. Toggle NS\n", option_index++);
+ printf("%i. Toggle experimental NS\n", option_index++);
+ printf("%i. Toggle EC\n", option_index++);
+ printf("%i. Select AEC\n", option_index++);
+ printf("%i. Select AECM\n", option_index++);
+ printf("%i. Get speaker volume\n", option_index++);
+ printf("%i. Set speaker volume\n", option_index++);
+ printf("%i. Get microphone volume\n", option_index++);
+ printf("%i. Set microphone volume\n", option_index++);
+ printf("%i. Play local file (audio_long16.pcm) \n", option_index++);
+ printf("%i. Change playout device \n", option_index++);
+ printf("%i. Change recording device \n", option_index++);
+ printf("%i. Toggle receive-side AGC \n", option_index++);
+ printf("%i. Toggle receive-side NS \n", option_index++);
+ printf("%i. AGC status \n", option_index++);
+ printf("%i. Toggle microphone mute \n", option_index++);
+ printf("%i. Get last error code \n", option_index++);
+ printf("%i. Toggle typing detection \n",
+ option_index++);
+ printf("%i. Record a PCM file \n", option_index++);
+ printf("%i. Play a previously recorded PCM file locally \n",
+ option_index++);
+ printf("%i. Play a previously recorded PCM file as microphone \n",
+ option_index++);
+ printf("%i. Add an additional file-playing channel \n", option_index++);
+ printf("%i. Remove a file-playing channel \n", option_index++);
+ printf("%i. Toggle Opus stereo (Opus must be selected again to apply "
+ "the setting) \n", option_index++);
+ printf("%i. Set Opus maximum playback rate \n", option_index++);
+ printf("%i. Toggle Opus DTX \n", option_index++);
+ printf("%i. Set bit rate (only take effect on codecs that allow the "
+ "change) \n", option_index++);
+ printf("%i. Toggle AECdump recording \n", option_index++);
+ printf("%i. Record RtcEventLog file of 30 seconds \n", option_index++);
+
+ printf("Select action or %i to stop the call: ", option_index);
+ int option_selection;
+ ASSERT_EQ(1, scanf("%i", &option_selection));
+
+ option_index = num_codecs;
+ if (option_selection < option_index) {
+ res = codec->GetCodec(option_selection, cinst);
+ VALIDATE;
+ if (strcmp(cinst.plname, "red") == 0) {
+ printf("Enabling RED\n");
+ res = rtp_rtcp->SetREDStatus(chan, true, cinst.pltype);
+ } else {
+ SetStereoIfOpus(opus_stereo, &cinst);
+ printf("Set primary codec\n");
+ res = codec->SetSendCodec(chan, cinst);
+ }
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ enable_cng = !enable_cng;
+ res = codec->SetVADStatus(0, enable_cng);
+ VALIDATE;
+ if (enable_cng)
+ printf("\n CNG is now on! \n");
+ else
+ printf("\n CNG is now off! \n");
+ } else if (option_selection == option_index++) {
+ enable_agc = !enable_agc;
+ res = apm->SetAgcStatus(enable_agc);
+ VALIDATE;
+ if (enable_agc)
+ printf("\n AGC is now on! \n");
+ else
+ printf("\n AGC is now off! \n");
+ } else if (option_selection == option_index++) {
+ enable_ns = !enable_ns;
+ res = apm->SetNsStatus(enable_ns);
+ VALIDATE;
+ if (enable_ns)
+ printf("\n NS is now on! \n");
+ else
+ printf("\n NS is now off! \n");
+ } else if (option_selection == option_index++) {
+ experimental_ns_enabled = !experimental_ns_enabled;
+ Config config;
+ config.Set<ExperimentalNs>(new ExperimentalNs(experimental_ns_enabled));
+ base1->audio_processing()->SetExtraOptions(config);
+ if (experimental_ns_enabled) {
+ printf("\n Experimental NS is now on!\n");
+ } else {
+ printf("\n Experimental NS is now off!\n");
+ }
+ } else if (option_selection == option_index++) {
+ enable_aec = !enable_aec;
+ res = apm->SetEcStatus(enable_aec, kEcUnchanged);
+ VALIDATE;
+ if (enable_aec)
+ printf("\n Echo control is now on! \n");
+ else
+ printf("\n Echo control is now off! \n");
+ } else if (option_selection == option_index++) {
+ res = apm->SetEcStatus(enable_aec, kEcAec);
+ VALIDATE;
+ printf("\n AEC selected! \n");
+ if (enable_aec)
+ printf(" (Echo control is on)\n");
+ else
+ printf(" (Echo control is off)\n");
+ } else if (option_selection == option_index++) {
+ res = apm->SetEcStatus(enable_aec, kEcAecm);
+ VALIDATE;
+ printf("\n AECM selected! \n");
+ if (enable_aec)
+ printf(" (Echo control is on)\n");
+ else
+ printf(" (Echo control is off)\n");
+ } else if (option_selection == option_index++) {
+ unsigned vol(0);
+ res = volume->GetSpeakerVolume(vol);
+ VALIDATE;
+ printf("\n Speaker Volume is %d \n", vol);
+ } else if (option_selection == option_index++) {
+ printf("Level: ");
+ int level;
+ ASSERT_EQ(1, scanf("%i", &level));
+ res = volume->SetSpeakerVolume(level);
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ unsigned vol(0);
+ res = volume->GetMicVolume(vol);
+ VALIDATE;
+ printf("\n Microphone Volume is %d \n", vol);
+ } else if (option_selection == option_index++) {
+ printf("Level: ");
+ int level;
+ ASSERT_EQ(1, scanf("%i", &level));
+ res = volume->SetMicVolume(level);
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ res = file->StartPlayingFileLocally(0, audio_filename.c_str());
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ // change the playout device with current call
+ int num_pd(-1);
+ res = hardware->GetNumOfPlayoutDevices(num_pd);
+ VALIDATE;
+
+ char dn[128] = { 0 };
+ char guid[128] = { 0 };
+
+ printf("\nPlayout devices (%d): \n", num_pd);
+ for (int i = 0; i < num_pd; ++i) {
+ res = hardware->GetPlayoutDeviceName(i, dn, guid);
+ VALIDATE;
+ printf(" %d: %s \n", i, dn);
+ }
+ printf("Select playout device: ");
+ ASSERT_EQ(1, scanf("%d", &num_pd));
+ // Will use plughw for hardware devices
+ res = hardware->SetPlayoutDevice(num_pd);
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ // change the recording device with current call
+ int num_rd(-1);
+
+ res = hardware->GetNumOfRecordingDevices(num_rd);
+ VALIDATE;
+
+ char dn[128] = { 0 };
+ char guid[128] = { 0 };
+
+ printf("Recording devices (%d): \n", num_rd);
+ for (int i = 0; i < num_rd; ++i) {
+ res = hardware->GetRecordingDeviceName(i, dn, guid);
+ VALIDATE;
+ printf(" %d: %s \n", i, dn);
+ }
+
+ printf("Select recording device: ");
+ ASSERT_EQ(1, scanf("%d", &num_rd));
+ printf("Setting sound devices \n");
+ // Will use plughw for hardware devices
+ res = hardware->SetRecordingDevice(num_rd);
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ // Remote AGC
+ enable_rx_agc = !enable_rx_agc;
+ res = apm->SetRxAgcStatus(chan, enable_rx_agc);
+ VALIDATE;
+ if (enable_rx_agc)
+ printf("\n Receive-side AGC is now on! \n");
+ else
+ printf("\n Receive-side AGC is now off! \n");
+ } else if (option_selection == option_index++) {
+ // Remote NS
+ enable_rx_ns = !enable_rx_ns;
+ res = apm->SetRxNsStatus(chan, enable_rx_ns);
+ VALIDATE;
+ if (enable_rx_ns)
+ printf("\n Receive-side NS is now on! \n");
+ else
+ printf("\n Receive-side NS is now off! \n");
+ } else if (option_selection == option_index++) {
+ AgcModes agcmode;
+ bool enable;
+ res = apm->GetAgcStatus(enable, agcmode);
+ VALIDATE
+ printf("\n AGC enable is %d, mode is %d \n", enable, agcmode);
+ } else if (option_selection == option_index++) {
+ // Toggle Mute on Microphone
+ res = volume->GetInputMute(chan, muted);
+ VALIDATE;
+ muted = !muted;
+ res = volume->SetInputMute(chan, muted);
+ VALIDATE;
+ if (muted)
+ printf("\n Microphone is now on mute! \n");
+ else
+ printf("\n Microphone is no longer on mute! \n");
+ } else if (option_selection == option_index++) {
+ // Get the last error code and print to screen
+ int err_code = 0;
+ err_code = base1->LastError();
+ if (err_code != -1)
+ printf("\n The last error code was %i.\n", err_code);
+ } else if (option_selection == option_index++) {
+ typing_detection= !typing_detection;
+ res = apm->SetTypingDetectionStatus(typing_detection);
+ VALIDATE;
+ if (typing_detection)
+ printf("\n Typing detection is now on!\n");
+ else
+ printf("\n Typing detection is now off!\n");
+ } else if (option_selection == option_index++) {
+ int stop_record = 1;
+ int file_source = 1;
+ printf("\n Select source of recorded file. ");
+ printf("\n 1. Record from microphone to file ");
+ printf("\n 2. Record from playout to file ");
+ printf("\n Enter your selection: \n");
+ ASSERT_EQ(1, scanf("%i", &file_source));
+ if (file_source == 1) {
+ printf("\n Start recording microphone as %s \n",
+ mic_filename.c_str());
+ res = file->StartRecordingMicrophone(mic_filename.c_str());
+ VALIDATE;
+ } else {
+ printf("\n Start recording playout as %s \n", play_filename.c_str());
+ res = file->StartRecordingPlayout(chan, play_filename.c_str());
+ VALIDATE;
+ }
+ while (stop_record != 0) {
+ printf("\n Type 0 to stop recording file \n");
+ ASSERT_EQ(1, scanf("%i", &stop_record));
+ }
+ if (file_source == 1) {
+ res = file->StopRecordingMicrophone();
+ VALIDATE;
+ } else {
+ res = file->StopRecordingPlayout(chan);
+ VALIDATE;
+ }
+ printf("\n File finished recording \n");
+ } else if (option_selection == option_index++) {
+ int file_type = 1;
+ int stop_play = 1;
+ printf("\n Select a file to play locally in a loop.");
+ printf("\n 1. Play %s", mic_filename.c_str());
+ printf("\n 2. Play %s", play_filename.c_str());
+ printf("\n Enter your selection\n");
+ ASSERT_EQ(1, scanf("%i", &file_type));
+ if (file_type == 1) {
+ printf("\n Start playing %s locally in a loop\n",
+ mic_filename.c_str());
+ res = file->StartPlayingFileLocally(chan, mic_filename.c_str(), true);
+ VALIDATE;
+ } else {
+ printf("\n Start playing %s locally in a loop\n",
+ play_filename.c_str());
+ res = file->StartPlayingFileLocally(chan, play_filename.c_str(),
+ true);
+ VALIDATE;
+ }
+ while (stop_play != 0) {
+ printf("\n Type 0 to stop playing file\n");
+ ASSERT_EQ(1, scanf("%i", &stop_play));
+ }
+ res = file->StopPlayingFileLocally(chan);
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ int file_type = 1;
+ int stop_play = 1;
+ printf("\n Select a file to play as microphone in a loop.");
+ printf("\n 1. Play %s", mic_filename.c_str());
+ printf("\n 2. Play %s", play_filename.c_str());
+ printf("\n Enter your selection\n");
+ ASSERT_EQ(1, scanf("%i", &file_type));
+ if (file_type == 1) {
+ printf("\n Start playing %s as mic in a loop\n",
+ mic_filename.c_str());
+ res = file->StartPlayingFileAsMicrophone(chan, mic_filename.c_str(),
+ true);
+ VALIDATE;
+ } else {
+ printf("\n Start playing %s as mic in a loop\n",
+ play_filename.c_str());
+ res = file->StartPlayingFileAsMicrophone(chan, play_filename.c_str(),
+ true);
+ VALIDATE;
+ }
+ while (stop_play != 0) {
+ printf("\n Type 0 to stop playing file\n");
+ ASSERT_EQ(1, scanf("%i", &stop_play));
+ }
+ res = file->StopPlayingFileAsMicrophone(chan);
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ if (channel_index < kMaxNumChannels) {
+ res = base1->StartReceive(channels[channel_index]);
+ VALIDATE;
+ res = base1->StartPlayout(channels[channel_index]);
+ VALIDATE;
+ res = base1->StartSend(channels[channel_index]);
+ VALIDATE;
+ res = file->StartPlayingFileAsMicrophone(channels[channel_index],
+ audio_filename.c_str(),
+ true,
+ false);
+ VALIDATE;
+ channel_index++;
+ printf("Using %d additional channels\n", channel_index);
+ } else {
+ printf("Max number of channels reached\n");
+ }
+ } else if (option_selection == option_index++) {
+ if (channel_index > 0) {
+ channel_index--;
+ res = file->StopPlayingFileAsMicrophone(channels[channel_index]);
+ VALIDATE;
+ res = base1->StopSend(channels[channel_index]);
+ VALIDATE;
+ res = base1->StopPlayout(channels[channel_index]);
+ VALIDATE;
+ res = base1->StopReceive(channels[channel_index]);
+ VALIDATE;
+ printf("Using %d additional channels\n", channel_index);
+ } else {
+ printf("All additional channels stopped\n");
+ }
+ } else if (option_selection == option_index++) {
+ opus_stereo = !opus_stereo;
+ if (opus_stereo)
+ printf("\n Opus stereo enabled (select Opus again to apply the "
+ "setting). \n");
+ else
+ printf("\n Opus mono enabled (select Opus again to apply the "
+ "setting). \n");
+ } else if (option_selection == option_index++) {
+ printf("\n Input maxium playback rate in Hz: ");
+ int max_playback_rate;
+ ASSERT_EQ(1, scanf("%i", &max_playback_rate));
+ res = codec->SetOpusMaxPlaybackRate(chan, max_playback_rate);
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ opus_dtx = !opus_dtx;
+ res = codec->SetOpusDtx(chan, opus_dtx);
+ VALIDATE;
+ printf("Opus DTX %s.\n", opus_dtx ? "enabled" : "disabled");
+ } else if (option_selection == option_index++) {
+ res = codec->GetSendCodec(chan, cinst);
+ VALIDATE;
+ printf("Current bit rate is %i bps, set to: ", cinst.rate);
+ int new_bitrate_bps;
+ ASSERT_EQ(1, scanf("%i", &new_bitrate_bps));
+ res = codec->SetBitRate(chan, new_bitrate_bps);
+ VALIDATE;
+ } else if (option_selection == option_index++) {
+ const char* kDebugFileName = "audio.aecdump";
+ if (debug_recording_started) {
+ apm->StopDebugRecording();
+ printf("Debug recording named %s stopped\n", kDebugFileName);
+ } else {
+ apm->StartDebugRecording(kDebugFileName);
+ printf("Debug recording named %s started\n", kDebugFileName);
+ }
+ debug_recording_started = !debug_recording_started;
+ } else if (option_selection == option_index++) {
+ const char* kDebugFileName = "eventlog.rel";
+ codec->GetEventLog()->StartLogging(kDebugFileName, 30000);
+ } else {
+ break;
+ }
+ }
+
+ if (debug_recording_started) {
+ apm->StopDebugRecording();
+ }
+
+ if (send) {
+ printf("Stop Send \n");
+ res = base1->StopSend(chan);
+ VALIDATE;
+ }
+
+ if (receive) {
+ printf("Stop Playout \n");
+ res = base1->StopPlayout(chan);
+ VALIDATE;
+
+#ifndef EXTERNAL_TRANSPORT
+ printf("Stop Listen \n");
+ res = base1->StopReceive(chan);
+ VALIDATE;
+#endif
+ }
+
+ while (channel_index > 0) {
+ --channel_index;
+ res = file->StopPlayingFileAsMicrophone(channels[channel_index]);
+ VALIDATE;
+ res = base1->StopSend(channels[channel_index]);
+ VALIDATE;
+ res = base1->StopPlayout(channels[channel_index]);
+ VALIDATE;
+ res = base1->StopReceive(channels[channel_index]);
+ VALIDATE;
+ }
+
+ printf("\n1. New call \n");
+ printf("2. Quit \n");
+ printf("Select action: ");
+ int end_option;
+ ASSERT_EQ(1, scanf("%i", &end_option));
+ newcall = (end_option == 1);
+ // Call loop
+ }
+
+ // Transports should be deleted before channel deletion.
+ delete voice_channel_transport;
+ for (int i = 0; i < kMaxNumChannels; ++i) {
+ delete voice_channel_transports[i];
+ voice_channel_transports[i] = NULL;
+ }
+
+ printf("Delete channels \n");
+ res = base1->DeleteChannel(chan);
+ VALIDATE;
+
+ for (int i = 0; i < kMaxNumChannels; ++i) {
+ res = base1->DeleteChannel(channels[i]);
+ VALIDATE;
+ }
+}