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 |