blob: 4f1aa03cfde0571c1df6d46d20efc90a68c9bcd6 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
andrew@webrtc.org63a50982012-05-02 23:56:37 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000011#include "webrtc/modules/audio_coding/main/test/APITest.h"
12
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <ctype.h>
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000014#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000017
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +000018#include <iostream>
19#include <ostream>
20#include <string>
21
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000022#include "testing/gtest/include/gtest/gtest.h"
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000023#include "webrtc/common.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000024#include "webrtc/common_types.h"
25#include "webrtc/engine_configurations.h"
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +000026#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000027#include "webrtc/modules/audio_coding/main/test/utility.h"
28#include "webrtc/system_wrappers/interface/event_wrapper.h"
29#include "webrtc/system_wrappers/interface/thread_wrapper.h"
30#include "webrtc/system_wrappers/interface/tick_util.h"
31#include "webrtc/system_wrappers/interface/trace.h"
32#include "webrtc/test/testsupport/fileutils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000033
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000034namespace webrtc {
35
niklase@google.com470e71d2011-07-07 08:21:25 +000036#define TEST_DURATION_SEC 600
niklase@google.com470e71d2011-07-07 08:21:25 +000037#define NUMBER_OF_SENDER_TESTS 6
niklase@google.com470e71d2011-07-07 08:21:25 +000038#define MAX_FILE_NAME_LENGTH_BYTE 500
kjellander@webrtc.org5490c712011-12-21 13:34:18 +000039#define CHECK_THREAD_NULLITY(myThread, S) \
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000040 if(myThread != NULL) { \
pbos@webrtc.org86639732015-03-13 00:06:21 +000041 (myThread)->Start(); \
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000042 } else { \
43 ADD_FAILURE() << S; \
44 }
niklase@google.com470e71d2011-07-07 08:21:25 +000045
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000046void APITest::Wait(uint32_t waitLengthMs) {
47 if (_randomTest) {
48 return;
49 } else {
50 EventWrapper* myEvent = EventWrapper::Create();
51 myEvent->Wait(waitLengthMs);
52 delete myEvent;
53 return;
54 }
niklase@google.com470e71d2011-07-07 08:21:25 +000055}
56
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000057APITest::APITest(const Config& config)
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +000058 : _acmA(AudioCodingModule::Create(1)),
59 _acmB(AudioCodingModule::Create(2)),
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000060 _channel_A2B(NULL),
61 _channel_B2A(NULL),
62 _writeToFile(true),
63 _pullEventA(NULL),
64 _pushEventA(NULL),
65 _processEventA(NULL),
66 _apiEventA(NULL),
67 _pullEventB(NULL),
68 _pushEventB(NULL),
69 _processEventB(NULL),
70 _apiEventB(NULL),
71 _codecCntrA(0),
72 _codecCntrB(0),
73 _thereIsEncoderA(false),
74 _thereIsEncoderB(false),
75 _thereIsDecoderA(false),
76 _thereIsDecoderB(false),
77 _sendVADA(false),
78 _sendDTXA(false),
79 _sendVADModeA(VADNormal),
80 _sendVADB(false),
81 _sendDTXB(false),
82 _sendVADModeB(VADNormal),
83 _minDelayA(0),
84 _minDelayB(0),
85 _dotPositionA(0),
86 _dotMoveDirectionA(1),
87 _dotPositionB(39),
88 _dotMoveDirectionB(-1),
89 _dtmfCallback(NULL),
90 _vadCallbackA(NULL),
91 _vadCallbackB(NULL),
92 _apiTestRWLock(*RWLockWrapper::CreateRWLock()),
93 _randomTest(false),
94 _testNumA(0),
95 _testNumB(1) {
96 int n;
97 for (n = 0; n < 32; n++) {
98 _payloadUsed[n] = false;
99 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000100
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000101 _movingDot[40] = '\0';
niklase@google.com470e71d2011-07-07 08:21:25 +0000102
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000103 for (int n = 0; n < 40; n++) {
104 _movingDot[n] = ' ';
105 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000106}
107
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000108APITest::~APITest() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000109 DELETE_POINTER(_channel_A2B);
110 DELETE_POINTER(_channel_B2A);
niklase@google.com470e71d2011-07-07 08:21:25 +0000111
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000112 DELETE_POINTER(_pushEventA);
113 DELETE_POINTER(_pullEventA);
114 DELETE_POINTER(_processEventA);
115 DELETE_POINTER(_apiEventA);
niklase@google.com470e71d2011-07-07 08:21:25 +0000116
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000117 DELETE_POINTER(_pushEventB);
118 DELETE_POINTER(_pullEventB);
119 DELETE_POINTER(_processEventB);
120 DELETE_POINTER(_apiEventB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000121
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000122 _inFileA.Close();
123 _outFileA.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000124
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000125 _inFileB.Close();
126 _outFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000127
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000128 DELETE_POINTER(_dtmfCallback);
129 DELETE_POINTER(_vadCallbackA);
130 DELETE_POINTER(_vadCallbackB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000131
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000132 delete &_apiTestRWLock;
niklase@google.com470e71d2011-07-07 08:21:25 +0000133}
134
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000135int16_t APITest::SetUp() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000136 CodecInst dummyCodec;
137 int lastPayloadType = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000138
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000139 int16_t numCodecs = _acmA->NumberOfCodecs();
140 for (uint8_t n = 0; n < numCodecs; n++) {
141 AudioCodingModule::Codec(n, &dummyCodec);
142 if ((STR_CASE_CMP(dummyCodec.plname, "CN") == 0)
143 && (dummyCodec.plfreq == 32000)) {
144 continue;
niklase@google.com470e71d2011-07-07 08:21:25 +0000145 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000146
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000147 printf("Register Receive Codec %s ", dummyCodec.plname);
niklase@google.com470e71d2011-07-07 08:21:25 +0000148
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000149 if ((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
150 // Check registration with an already occupied payload type
151 int currentPayloadType = dummyCodec.pltype;
152 dummyCodec.pltype = 97; //lastPayloadType;
153 CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
154 dummyCodec.pltype = currentPayloadType;
155 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000156
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000157 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
158 // test if re-registration works;
159 CodecInst nextCodec;
160 int currentPayloadType = dummyCodec.pltype;
161 AudioCodingModule::Codec(n + 1, &nextCodec);
162 dummyCodec.pltype = nextCodec.pltype;
163 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
164 _acmB->RegisterReceiveCodec(dummyCodec);
165 }
166 dummyCodec.pltype = currentPayloadType;
167 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000168
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000169 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
170 // test if un-registration works;
171 CodecInst nextCodec;
172 AudioCodingModule::Codec(n + 1, &nextCodec);
173 nextCodec.pltype = dummyCodec.pltype;
174 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
175 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
176 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
177 }
178 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000179
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000180 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
181 printf(" side A done!");
182 CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
183 printf(" side B done!\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000184
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000185 if (!strcmp(dummyCodec.plname, "CN")) {
186 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
187 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
188 }
189 lastPayloadType = dummyCodec.pltype;
190 if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
191 _payloadUsed[lastPayloadType - 96] = true;
192 }
193 }
194 _thereIsDecoderA = true;
195 _thereIsDecoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000196
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000197 // Register Send Codec
198 AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
199 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
200 _thereIsEncoderA = true;
201 //
202 AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
203 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
204 _thereIsEncoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000205
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000206 uint16_t frequencyHz;
niklase@google.com470e71d2011-07-07 08:21:25 +0000207
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000208 printf("\n\nAPI Test\n");
209 printf("========\n");
210 printf("Hit enter to accept the default values indicated in []\n\n");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000211
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000212 //--- Input A
213 std::string file_name = webrtc::test::ResourcePath(
214 "audio_coding/testfile32kHz", "pcm");
215 frequencyHz = 32000;
216 printf("Enter input file at side A [%s]: ", file_name.c_str());
217 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
218 _inFileA.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000219
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000220 //--- Output A
221 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
222 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
223 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
224 _outFileA.Open(out_file_a, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000225
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000226 //--- Input B
227 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
228 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
229 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
230 _inFileB.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000231
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000232 //--- Output B
233 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
234 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
235 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
236 _outFileB.Open(out_file_b, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000237
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000238 //--- Set A-to-B channel
239 _channel_A2B = new Channel(2);
240 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000241 _channel_A2B->RegisterReceiverACM(_acmB.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000242
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000243 //--- Set B-to-A channel
244 _channel_B2A = new Channel(1);
245 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000246 _channel_B2A->RegisterReceiverACM(_acmA.get());
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +0000247
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000248 //--- EVENT TIMERS
249 // A
250 _pullEventA = EventWrapper::Create();
251 _pushEventA = EventWrapper::Create();
252 _processEventA = EventWrapper::Create();
253 _apiEventA = EventWrapper::Create();
254 // B
255 _pullEventB = EventWrapper::Create();
256 _pushEventB = EventWrapper::Create();
257 _processEventB = EventWrapper::Create();
258 _apiEventB = EventWrapper::Create();
259
260 //--- I/O params
261 // A
262 _outFreqHzA = _outFileA.SamplingFrequency();
263 // B
264 _outFreqHzB = _outFileB.SamplingFrequency();
265
266 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
267
268 char print[11];
269
270 // Create a trace file.
271 Trace::CreateTrace();
272 Trace::SetTraceFile(
273 (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
274
275 printf("\nRandom Test (y/n)?");
276 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
277 print[10] = '\0';
278 if (strstr(print, "y") != NULL) {
279 _randomTest = true;
280 _verbose = false;
281 _writeToFile = false;
282 } else {
283 _randomTest = false;
284 printf("\nPrint Tests (y/n)? ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000285 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000286 print[10] = '\0';
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000287 if (strstr(print, "y") == NULL) {
288 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
289 _verbose = false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000290 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000291 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000292
293#ifdef WEBRTC_DTMF_DETECTION
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000294 _dtmfCallback = new DTMFDetector;
niklase@google.com470e71d2011-07-07 08:21:25 +0000295#endif
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000296 _vadCallbackA = new VADCallback;
297 _vadCallbackB = new VADCallback;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000298
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000299 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000300}
301
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000302bool APITest::PushAudioThreadA(void* obj) {
303 return static_cast<APITest*>(obj)->PushAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000304}
305
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000306bool APITest::PushAudioThreadB(void* obj) {
307 return static_cast<APITest*>(obj)->PushAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000308}
309
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000310bool APITest::PullAudioThreadA(void* obj) {
311 return static_cast<APITest*>(obj)->PullAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000312}
313
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000314bool APITest::PullAudioThreadB(void* obj) {
315 return static_cast<APITest*>(obj)->PullAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000316}
317
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000318bool APITest::ProcessThreadA(void* obj) {
319 return static_cast<APITest*>(obj)->ProcessRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000320}
321
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000322bool APITest::ProcessThreadB(void* obj) {
323 return static_cast<APITest*>(obj)->ProcessRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000324}
325
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000326bool APITest::APIThreadA(void* obj) {
327 return static_cast<APITest*>(obj)->APIRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000328}
329
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000330bool APITest::APIThreadB(void* obj) {
331 return static_cast<APITest*>(obj)->APIRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000332}
333
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000334bool APITest::PullAudioRunA() {
335 _pullEventA->Wait(100);
336 AudioFrame audioFrame;
337 if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame) < 0) {
338 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000340 ReadLockScoped rl(_apiTestRWLock);
341 thereIsDecoder = _thereIsDecoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000343 if (thereIsDecoder) {
344 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000345 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000346 } else {
347 if (_writeToFile) {
348 _outFileA.Write10MsData(audioFrame);
349 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000350 }
351 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000352}
353
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000354bool APITest::PullAudioRunB() {
355 _pullEventB->Wait(100);
356 AudioFrame audioFrame;
357 if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame) < 0) {
358 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000359 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000360 ReadLockScoped rl(_apiTestRWLock);
361 thereIsDecoder = _thereIsDecoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000362 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000363 if (thereIsDecoder) {
364 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
365 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000366 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000367 } else {
368 if (_writeToFile) {
369 _outFileB.Write10MsData(audioFrame);
370 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000371 }
372 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000373}
374
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000375bool APITest::PushAudioRunA() {
376 _pushEventA->Wait(100);
377 AudioFrame audioFrame;
378 _inFileA.Read10MsData(audioFrame);
379 if (_acmA->Add10MsData(audioFrame) < 0) {
380 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000381 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000382 ReadLockScoped rl(_apiTestRWLock);
383 thereIsEncoder = _thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000384 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000385 if (thereIsEncoder) {
386 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
387 }
388 }
389 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000390}
391
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000392bool APITest::PushAudioRunB() {
393 _pushEventB->Wait(100);
394 AudioFrame audioFrame;
395 _inFileB.Read10MsData(audioFrame);
396 if (_acmB->Add10MsData(audioFrame) < 0) {
397 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000398 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000399 ReadLockScoped rl(_apiTestRWLock);
400 thereIsEncoder = _thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000401 }
402
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000403 if (thereIsEncoder) {
404 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
405 }
406 }
407
408 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000409}
410
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000411bool APITest::ProcessRunA() {
412 _processEventA->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000413 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000414}
415
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000416bool APITest::ProcessRunB() {
417 _processEventB->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000418 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000419}
420
421/*/
422 *
423 * In side A we test the APIs which are related to sender Side.
424 *
425/*/
426
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000427void APITest::RunTest(char thread) {
428 int testNum;
429 {
430 WriteLockScoped cs(_apiTestRWLock);
431 if (thread == 'A') {
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +0000432 _testNumA = (_testNumB + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000433 testNum = _testNumA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000434
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000435 _movingDot[_dotPositionA] = ' ';
436 if (_dotPositionA == 0) {
437 _dotMoveDirectionA = 1;
438 }
439 if (_dotPositionA == 19) {
440 _dotMoveDirectionA = -1;
441 }
442 _dotPositionA += _dotMoveDirectionA;
443 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
444 } else {
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +0000445 _testNumB = (_testNumA + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000446 testNum = _testNumB;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000447
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000448 _movingDot[_dotPositionB] = ' ';
449 if (_dotPositionB == 20) {
450 _dotMoveDirectionB = 1;
451 }
452 if (_dotPositionB == 39) {
453 _dotMoveDirectionB = -1;
454 }
455 _dotPositionB += _dotMoveDirectionB;
456 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
niklase@google.com470e71d2011-07-07 08:21:25 +0000457 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000458 //fprintf(stderr, "%c: %d \n", thread, testNum);
459 //fflush(stderr);
460 }
461 switch (testNum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000462 case 0:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000463 CurrentCodec('A');
464 ChangeCodec('A');
465 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000466 case 1:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000467 TestPlayout('B');
468 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000469 case 2:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000470 if (!_randomTest) {
471 fprintf(stdout, "\nTesting Delay ...\n");
472 }
473 TestDelay('A');
474 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000475 case 3:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000476 TestSendVAD('A');
477 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000478 case 4:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000479 TestRegisteration('A');
480 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000481 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000482 fprintf(stderr, "Wrong Test Number\n");
marpan@webrtc.org4765ca52014-11-03 20:10:26 +0000483 getc(stdin);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000484 exit(1);
485 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000486}
487
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000488bool APITest::APIRunA() {
489 _apiEventA->Wait(50);
niklase@google.com470e71d2011-07-07 08:21:25 +0000490
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000491 bool randomTest;
492 {
493 ReadLockScoped rl(_apiTestRWLock);
494 randomTest = _randomTest;
495 }
496 if (randomTest) {
497 RunTest('A');
498 } else {
499 CurrentCodec('A');
500 ChangeCodec('A');
501 TestPlayout('B');
502 if (_codecCntrA == 0) {
503 fprintf(stdout, "\nTesting Delay ...\n");
504 TestDelay('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000505 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000506 // VAD TEST
507 TestSendVAD('A');
508 TestRegisteration('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000509 }
510 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000511}
512
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000513bool APITest::APIRunB() {
514 _apiEventB->Wait(50);
515 bool randomTest;
516 {
517 ReadLockScoped rl(_apiTestRWLock);
518 randomTest = _randomTest;
519 }
520 //_apiEventB->Wait(2000);
521 if (randomTest) {
522 RunTest('B');
523 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000524
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000525 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000526}
527
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000528void APITest::Perform() {
529 SetUp();
niklase@google.com470e71d2011-07-07 08:21:25 +0000530
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000531 //--- THREADS
532 // A
533 // PUSH
534 ThreadWrapper* myPushAudioThreadA = ThreadWrapper::CreateThread(
535 PushAudioThreadA, this, kNormalPriority, "PushAudioThreadA");
536 CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
537 // PULL
538 ThreadWrapper* myPullAudioThreadA = ThreadWrapper::CreateThread(
539 PullAudioThreadA, this, kNormalPriority, "PullAudioThreadA");
540 CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
541 // Process
542 ThreadWrapper* myProcessThreadA = ThreadWrapper::CreateThread(
543 ProcessThreadA, this, kNormalPriority, "ProcessThreadA");
544 CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
545 // API
546 ThreadWrapper* myAPIThreadA = ThreadWrapper::CreateThread(APIThreadA, this,
547 kNormalPriority,
548 "APIThreadA");
549 CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
550 // B
551 // PUSH
552 ThreadWrapper* myPushAudioThreadB = ThreadWrapper::CreateThread(
553 PushAudioThreadB, this, kNormalPriority, "PushAudioThreadB");
554 CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
555 // PULL
556 ThreadWrapper* myPullAudioThreadB = ThreadWrapper::CreateThread(
557 PullAudioThreadB, this, kNormalPriority, "PullAudioThreadB");
558 CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
559 // Process
560 ThreadWrapper* myProcessThreadB = ThreadWrapper::CreateThread(
561 ProcessThreadB, this, kNormalPriority, "ProcessThreadB");
562 CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
563 // API
564 ThreadWrapper* myAPIThreadB = ThreadWrapper::CreateThread(APIThreadB, this,
565 kNormalPriority,
566 "APIThreadB");
567 CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000568
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000569 //_apiEventA->StartTimer(true, 5000);
570 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000571
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000572 _processEventA->StartTimer(true, 10);
573 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000574
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000575 _pullEventA->StartTimer(true, 10);
576 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000577
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000578 _pushEventA->StartTimer(true, 10);
579 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000580
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000581 // Keep main thread waiting for sender/receiver
582 // threads to complete
583 EventWrapper* completeEvent = EventWrapper::Create();
584 uint64_t startTime = TickTime::MillisecondTimestamp();
585 uint64_t currentTime;
586 // Run test in 2 minutes (120000 ms).
587 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000588 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000589 //ReadLockScoped rl(_apiTestRWLock);
590 //fprintf(stderr, "\r%s", _movingDot);
591 }
592 //fflush(stderr);
593 completeEvent->Wait(50);
594 currentTime = TickTime::MillisecondTimestamp();
595 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000596
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000597 //completeEvent->Wait(0xFFFFFFFF);
598 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
599 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000600
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000601 myPushAudioThreadA->Stop();
602 myPullAudioThreadA->Stop();
603 myProcessThreadA->Stop();
604 myAPIThreadA->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000605
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000606 delete myPushAudioThreadA;
607 delete myPullAudioThreadA;
608 delete myProcessThreadA;
609 delete myAPIThreadA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000610
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000611 myPushAudioThreadB->Stop();
612 myPullAudioThreadB->Stop();
613 myProcessThreadB->Stop();
614 myAPIThreadB->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000615
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000616 delete myPushAudioThreadB;
617 delete myPullAudioThreadB;
618 delete myProcessThreadB;
619 delete myAPIThreadB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000620}
621
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000622void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000623
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000624 bool dtxEnabled;
625 bool vadEnabled;
626 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000627
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000628 if (side == 'A') {
629 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
630 _acmA->RegisterVADCallback(NULL);
631 _vadCallbackA->Reset();
632 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000633
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000634 if (!_randomTest) {
635 if (_verbose) {
636 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
637 vadEnabled ? "ON" : "OFF", (int) vadMode);
638 Wait(5000);
639 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
640 } else {
641 Wait(5000);
642 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
643 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
644 (int) vadMode, _channel_A2B->BitRate());
645 }
646 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000647 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000648
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000649 if (dtxEnabled != _sendDTXA) {
650 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000651 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000652 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
653 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
654 }
655 if ((vadMode != _sendVADModeA) && vadEnabled) {
656 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
657 }
658 } else {
659 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
660
661 _acmB->RegisterVADCallback(NULL);
662 _vadCallbackB->Reset();
663 _acmB->RegisterVADCallback(_vadCallbackB);
664
665 if (!_randomTest) {
666 if (_verbose) {
667 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
668 vadEnabled ? "ON" : "OFF", (int) vadMode);
669 Wait(5000);
670 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
671 } else {
672 Wait(5000);
673 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
674 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
675 (int) vadMode, _channel_B2A->BitRate());
676 }
677 _vadCallbackB->PrintFrameTypes();
678 }
679
680 if (dtxEnabled != _sendDTXB) {
681 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
682 }
683 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
684 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
685 }
686 if ((vadMode != _sendVADModeB) && vadEnabled) {
687 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
688 }
689 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000690}
691
692// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000693void APITest::TestDelay(char side) {
694 AudioCodingModule* myACM;
695 Channel* myChannel;
696 int32_t* myMinDelay;
697 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000698
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000699 uint32_t inTimestamp = 0;
700 uint32_t outTimestamp = 0;
701 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000702
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000703 double averageEstimDelay = 0;
704 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000705
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000706 CircularBuffer estimDelayCB(100);
707 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000708
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000709 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000710 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000711 myChannel = _channel_B2A;
712 myMinDelay = &_minDelayA;
713 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000714 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000715 myChannel = _channel_A2B;
716 myMinDelay = &_minDelayB;
717 }
718
719 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
720
721 inTimestamp = myChannel->LastInTimestamp();
722 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
723
724 if (!_randomTest) {
725 myEvent->StartTimer(true, 30);
726 int n = 0;
727 int settlePoint = 5000;
728 while (n < settlePoint + 400) {
729 myEvent->Wait(1000);
730
731 inTimestamp = myChannel->LastInTimestamp();
732 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
733
734 //std::cout << outTimestamp << std::endl << std::flush;
735 estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
736 / ((double) myACM->ReceiveFrequency() / 1000.0);
737
738 estimDelayCB.Update(estimDelay);
739
740 estimDelayCB.ArithMean(averageEstimDelay);
741 //printf("\n %6.1f \n", estimDelay);
742 //std::cout << " " << std::flush;
743
744 if (_verbose) {
745 fprintf(stdout,
746 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
747 *myMinDelay, averageDelay, averageEstimDelay);
748 std::cout << " " << std::flush;
749 }
750 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
751 settlePoint = n;
752 }
753 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000754 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000755 myEvent->StopTimer();
756 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000757
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000758 if ((!_verbose) && (!_randomTest)) {
759 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000760 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000761 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000762
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000763 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000764
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000765 NetworkStatistics networkStat;
766 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000767
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000768 if (!_randomTest) {
769 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
770 fprintf(stdout, "--------------------------------------\n");
771 fprintf(stdout, "buffer-size............. %d\n",
772 networkStat.currentBufferSize);
773 fprintf(stdout, "Preferred buffer-size... %d\n",
774 networkStat.preferredBufferSize);
775 fprintf(stdout, "Peaky jitter mode........%d\n",
776 networkStat.jitterPeaksFound);
777 fprintf(stdout, "packet-size rate........ %d\n",
778 networkStat.currentPacketLossRate);
779 fprintf(stdout, "discard rate............ %d\n",
780 networkStat.currentDiscardRate);
781 fprintf(stdout, "expand rate............. %d\n",
782 networkStat.currentExpandRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000783 fprintf(stdout, "speech expand rate...... %d\n",
784 networkStat.currentSpeechExpandRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000785 fprintf(stdout, "Preemptive rate......... %d\n",
786 networkStat.currentPreemptiveRate);
787 fprintf(stdout, "Accelerate rate......... %d\n",
788 networkStat.currentAccelerateRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000789 fprintf(stdout, "Secondary decoded rate.. %d\n",
790 networkStat.currentSecondaryDecodedRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000791 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
792 fprintf(stdout, "Mean waiting time....... %d\n",
793 networkStat.meanWaitingTimeMs);
794 fprintf(stdout, "Median waiting time..... %d\n",
795 networkStat.medianWaitingTimeMs);
796 fprintf(stdout, "Min waiting time........ %d\n",
797 networkStat.minWaitingTimeMs);
798 fprintf(stdout, "Max waiting time........ %d\n",
799 networkStat.maxWaitingTimeMs);
800 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000801
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000802 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000803
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000804 if (!_randomTest) {
805 myEvent->Wait(500);
806 fprintf(stdout, "\n");
807 fprintf(stdout, "\n");
808 }
809 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000810}
811
812// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000813void APITest::TestRegisteration(char sendSide) {
814 AudioCodingModule* sendACM;
815 AudioCodingModule* receiveACM;
816 bool* thereIsDecoder;
817 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000818
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000819 if (!_randomTest) {
820 fprintf(stdout, "\n\n");
821 fprintf(stdout,
822 "---------------------------------------------------------\n");
823 fprintf(stdout, " Unregister/register Receive Codec\n");
824 fprintf(stdout,
825 "---------------------------------------------------------\n");
826 }
827
828 switch (sendSide) {
829 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000830 sendACM = _acmA.get();
831 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000832 thereIsDecoder = &_thereIsDecoderB;
833 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000834 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000835 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000836 sendACM = _acmB.get();
837 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000838 thereIsDecoder = &_thereIsDecoderA;
839 break;
840 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000841 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000842 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
843 sendSide);
844 exit(-1);
845 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000846
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000847 CodecInst myCodec;
848 if (sendACM->SendCodec(&myCodec) < 0) {
849 AudioCodingModule::Codec(_codecCntrA, &myCodec);
850 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000851
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000852 if (!_randomTest) {
853 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
854 fflush (stdout);
855 }
856 {
857 WriteLockScoped wl(_apiTestRWLock);
858 *thereIsDecoder = false;
859 }
860 //myEvent->Wait(20);
861 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
862 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000863
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000864 int currentPayload = myCodec.pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000865
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000866 if (!FixedPayloadTypeCodec(myCodec.plname)) {
867 int32_t i;
868 for (i = 0; i < 32; i++) {
869 if (!_payloadUsed[i]) {
870 if (!_randomTest) {
871 fprintf(stdout,
872 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000873 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000874 //myCodec.pltype = i + 96;
875 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
876 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
877 //myEvent->Wait(20);
878 //{
879 // WriteLockScoped wl(_apiTestRWLock);
880 // *thereIsDecoder = true;
881 //}
882 Wait(1000);
883
884 if (!_randomTest) {
885 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000886 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000887 //{
888 // WriteLockScoped wl(_apiTestRWLock);
889 // *thereIsDecoder = false;
890 //}
891 //myEvent->Wait(20);
892 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
893 Wait(1000);
894
895 myCodec.pltype = currentPayload;
896 if (!_randomTest) {
897 fprintf(stdout,
898 "Register receive codec with default Payload, AUDIO BACK.\n");
899 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000900 }
901 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000902 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000903 myEvent->Wait(20);
904 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000905 WriteLockScoped wl(_apiTestRWLock);
906 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000907 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000908 Wait(1000);
909
910 break;
911 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000912 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000913 if (i == 32) {
914 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
915 {
916 WriteLockScoped wl(_apiTestRWLock);
917 *thereIsDecoder = true;
918 }
919 }
920 } else {
921 if (!_randomTest) {
922 fprintf(stdout,
923 "Register receive codec with fixed Payload, AUDIO BACK.\n");
924 fflush (stdout);
925 }
926 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
927 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
928 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
929 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000930 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000931 WriteLockScoped wl(_apiTestRWLock);
932 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000933 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000934 }
935 delete myEvent;
936 if (!_randomTest) {
937 fprintf(stdout,
938 "---------------------------------------------------------\n");
939 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000940}
941
942// Playout Mode, background noise mode.
943// Receiver Frequency, playout frequency.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000944void APITest::TestPlayout(char receiveSide) {
945 AudioCodingModule* receiveACM;
946 AudioPlayoutMode* playoutMode = NULL;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000947 switch (receiveSide) {
948 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000949 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000950 playoutMode = &_playoutModeA;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000951 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000952 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000953 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000954 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000955 playoutMode = &_playoutModeB;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000956 break;
957 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000958 default:
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000959 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000960 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000961
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000962 int32_t receiveFreqHz = receiveACM->ReceiveFrequency();
963 int32_t playoutFreqHz = receiveACM->PlayoutFrequency();
964
965 CHECK_ERROR_MT(receiveFreqHz);
966 CHECK_ERROR_MT(playoutFreqHz);
967
niklase@google.com470e71d2011-07-07 08:21:25 +0000968
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000969 char playoutString[25];
970 switch (*playoutMode) {
971 case voice: {
972 *playoutMode = fax;
973 strncpy(playoutString, "FAX", 25);
974 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000975 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000976 case fax: {
977 *playoutMode = streaming;
978 strncpy(playoutString, "Streaming", 25);
979 break;
980 }
981 case streaming: {
982 *playoutMode = voice;
983 strncpy(playoutString, "Voice", 25);
984 break;
985 }
986 default:
987 *playoutMode = voice;
988 strncpy(playoutString, "Voice", 25);
989 }
990 CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
991 playoutString[24] = '\0';
992
993 if (!_randomTest) {
994 fprintf(stdout, "\n");
995 fprintf(stdout, "In Side %c\n", receiveSide);
996 fprintf(stdout, "---------------------------------\n");
997 fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
998 fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
999 fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001000 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001001}
1002
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001003void APITest::TestSendVAD(char side) {
1004 if (_randomTest) {
1005 return;
1006 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001007
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001008 bool* vad;
1009 bool* dtx;
1010 ACMVADMode* mode;
1011 Channel* myChannel;
1012 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +00001013
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001014 CodecInst myCodec;
1015 if (!_randomTest) {
1016 fprintf(stdout, "\n\n");
1017 fprintf(stdout, "-----------------------------------------------\n");
1018 fprintf(stdout, " Test VAD API\n");
1019 fprintf(stdout, "-----------------------------------------------\n");
1020 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001021
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001022 if (side == 'A') {
1023 AudioCodingModule::Codec(_codecCntrA, &myCodec);
1024 vad = &_sendVADA;
1025 dtx = &_sendDTXA;
1026 mode = &_sendVADModeA;
1027 myChannel = _channel_A2B;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001028 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001029 } else {
1030 AudioCodingModule::Codec(_codecCntrB, &myCodec);
1031 vad = &_sendVADB;
1032 dtx = &_sendDTXB;
1033 mode = &_sendVADModeB;
1034 myChannel = _channel_B2A;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001035 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001036 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001037
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001038 CheckVADStatus(side);
1039 if (!_randomTest) {
1040 fprintf(stdout, "\n\n");
1041 }
1042
1043 switch (*mode) {
1044 case VADNormal:
1045 *vad = true;
1046 *dtx = true;
1047 *mode = VADAggr;
1048 break;
1049 case VADLowBitrate:
1050 *vad = true;
1051 *dtx = true;
1052 *mode = VADVeryAggr;
1053 break;
1054 case VADAggr:
1055 *vad = true;
1056 *dtx = true;
1057 *mode = VADLowBitrate;
1058 break;
1059 case VADVeryAggr:
1060 *vad = false;
1061 *dtx = false;
1062 *mode = VADNormal;
1063 break;
1064 default:
1065 *mode = VADNormal;
1066 }
1067
1068 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
1069
1070 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1071 myChannel->ResetStats();
1072
1073 CheckVADStatus(side);
1074 if (!_randomTest) {
1075 fprintf(stdout, "\n");
1076 fprintf(stdout, "-----------------------------------------------\n");
1077 }
1078
1079 // Fault Test
1080 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
1081 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +00001082
1083}
1084
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001085void APITest::CurrentCodec(char side) {
1086 CodecInst myCodec;
1087 if (side == 'A') {
1088 _acmA->SendCodec(&myCodec);
1089 } else {
1090 _acmB->SendCodec(&myCodec);
1091 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001092
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001093 if (!_randomTest) {
1094 fprintf(stdout, "\n\n");
1095 fprintf(stdout, "Send codec in Side A\n");
1096 fprintf(stdout, "----------------------------\n");
1097 fprintf(stdout, "Name................. %s\n", myCodec.plname);
1098 fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
1099 fprintf(stdout, "Rate................. %d\n", myCodec.rate);
1100 fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
1101 fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
1102 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001103
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001104 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001105}
1106
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001107void APITest::ChangeCodec(char side) {
1108 CodecInst myCodec;
1109 AudioCodingModule* myACM;
1110 uint8_t* codecCntr;
1111 bool* thereIsEncoder;
1112 bool* vad;
1113 bool* dtx;
1114 ACMVADMode* mode;
1115 Channel* myChannel;
1116 // Reset and Wait
1117 if (!_randomTest) {
1118 fprintf(stdout, "Reset Encoder Side A \n");
1119 }
1120 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001121 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001122 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001123 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001124 WriteLockScoped wl(_apiTestRWLock);
1125 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001126 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001127 vad = &_sendVADA;
1128 dtx = &_sendDTXA;
1129 mode = &_sendVADModeA;
1130 myChannel = _channel_A2B;
1131 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001132 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001133 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001134 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001135 WriteLockScoped wl(_apiTestRWLock);
1136 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001137 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001138 vad = &_sendVADB;
1139 dtx = &_sendDTXB;
1140 mode = &_sendVADModeB;
1141 myChannel = _channel_B2A;
1142 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001143
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001144 myACM->ResetEncoder();
1145 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001146
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001147 // Register the next codec
1148 do {
1149 *codecCntr =
1150 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1151 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001152
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001153 if (*codecCntr == 0) {
1154 //printf("Initialize Sender Side A \n");
1155 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001156 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001157 *thereIsEncoder = false;
1158 }
1159 CHECK_ERROR_MT(myACM->InitializeSender());
1160 Wait(1000);
1161
1162 // After Initialization CN is lost, re-register them
1163 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1164 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1165 }
1166 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1167 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1168 }
1169 // VAD & DTX are disabled after initialization
1170 *vad = false;
1171 *dtx = false;
1172 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001173 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001174
1175 AudioCodingModule::Codec(*codecCntr, &myCodec);
1176 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1177 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1178 || !STR_CASE_CMP(myCodec.plname, "RED"));
1179
1180 if (!_randomTest) {
1181 fprintf(stdout,"\n=====================================================\n");
1182 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1183 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1184 }
1185 //std::cout<< std::flush;
1186
1187 // NO DTX for supe-wideband codec at this point
1188 if (myCodec.plfreq == 32000) {
1189 *dtx = false;
1190 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1191
1192 }
1193
1194 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1195 myChannel->ResetStats();
1196 {
1197 WriteLockScoped wl(_apiTestRWLock);
1198 *thereIsEncoder = true;
1199 }
1200 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001201}
1202
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001203} // namespace webrtc