Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / voice_engine / test / cmd_test / voe_cmd_test.cc
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 }