aboutsummaryrefslogtreecommitdiff
path: root/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc
diff options
context:
space:
mode:
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;
+ }
+}