blob: a9e2e710deb0ffcb851d60add757c1314559ac47 [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"
23#include "webrtc/common_types.h"
24#include "webrtc/engine_configurations.h"
turaj@webrtc.org367baa62013-09-18 00:36:11 +000025#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000026#include "webrtc/modules/audio_coding/main/test/utility.h"
27#include "webrtc/system_wrappers/interface/event_wrapper.h"
28#include "webrtc/system_wrappers/interface/thread_wrapper.h"
29#include "webrtc/system_wrappers/interface/tick_util.h"
30#include "webrtc/system_wrappers/interface/trace.h"
31#include "webrtc/test/testsupport/fileutils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000032
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000033namespace webrtc {
34
niklase@google.com470e71d2011-07-07 08:21:25 +000035#define TEST_DURATION_SEC 600
niklase@google.com470e71d2011-07-07 08:21:25 +000036#define NUMBER_OF_SENDER_TESTS 6
niklase@google.com470e71d2011-07-07 08:21:25 +000037#define MAX_FILE_NAME_LENGTH_BYTE 500
kjellander@webrtc.org5490c712011-12-21 13:34:18 +000038#define CHECK_THREAD_NULLITY(myThread, S) \
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000039 if(myThread != NULL) { \
40 unsigned int i; \
41 (myThread)->Start(i); \
42 } 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
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000057APITest::APITest()
andrew@webrtc.org89df0922013-09-12 01:27:43 +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));
241 _channel_A2B->RegisterReceiverACM(_acmB);
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));
246 _channel_B2A->RegisterReceiverACM(_acmA);
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);
413 if (_acmA->Process() < 0) {
414 // do not print error message if there is no encoder
415 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000416 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000417 ReadLockScoped rl(_apiTestRWLock);
418 thereIsEncoder = _thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000419 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000420
421 if (thereIsEncoder) {
422 fprintf(stderr, "\n>>>>> Process Failed at A <<<<<\n");
423 }
424 }
425 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000426}
427
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000428bool APITest::ProcessRunB() {
429 _processEventB->Wait(100);
430 if (_acmB->Process() < 0) {
431 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000432 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000433 ReadLockScoped rl(_apiTestRWLock);
434 thereIsEncoder = _thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000435 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000436 if (thereIsEncoder) {
437 fprintf(stderr, "\n>>>>> Process Failed at B <<<<<\n");
438 }
439 }
440 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000441}
442
443/*/
444 *
445 * In side A we test the APIs which are related to sender Side.
446 *
447/*/
448
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000449void APITest::RunTest(char thread) {
450 int testNum;
451 {
452 WriteLockScoped cs(_apiTestRWLock);
453 if (thread == 'A') {
turaj@webrtc.org367baa62013-09-18 00:36:11 +0000454 _testNumA = (_testNumB + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000455 testNum = _testNumA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000456
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000457 _movingDot[_dotPositionA] = ' ';
458 if (_dotPositionA == 0) {
459 _dotMoveDirectionA = 1;
460 }
461 if (_dotPositionA == 19) {
462 _dotMoveDirectionA = -1;
463 }
464 _dotPositionA += _dotMoveDirectionA;
465 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
466 } else {
turaj@webrtc.org367baa62013-09-18 00:36:11 +0000467 _testNumB = (_testNumA + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000468 testNum = _testNumB;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000469
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000470 _movingDot[_dotPositionB] = ' ';
471 if (_dotPositionB == 20) {
472 _dotMoveDirectionB = 1;
473 }
474 if (_dotPositionB == 39) {
475 _dotMoveDirectionB = -1;
476 }
477 _dotPositionB += _dotMoveDirectionB;
478 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
niklase@google.com470e71d2011-07-07 08:21:25 +0000479 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000480 //fprintf(stderr, "%c: %d \n", thread, testNum);
481 //fflush(stderr);
482 }
483 switch (testNum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000484 case 0:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000485 CurrentCodec('A');
486 ChangeCodec('A');
487 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000488 case 1:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000489 TestPlayout('B');
490 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000491 case 2:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000492 if (!_randomTest) {
493 fprintf(stdout, "\nTesting Delay ...\n");
494 }
495 TestDelay('A');
496 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000497 case 3:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000498 TestSendVAD('A');
499 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000500 case 4:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000501 TestRegisteration('A');
502 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000503 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000504 fprintf(stderr, "Wrong Test Number\n");
505 getchar();
506 exit(1);
507 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000508}
509
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000510bool APITest::APIRunA() {
511 _apiEventA->Wait(50);
niklase@google.com470e71d2011-07-07 08:21:25 +0000512
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000513 bool randomTest;
514 {
515 ReadLockScoped rl(_apiTestRWLock);
516 randomTest = _randomTest;
517 }
518 if (randomTest) {
519 RunTest('A');
520 } else {
521 CurrentCodec('A');
522 ChangeCodec('A');
523 TestPlayout('B');
524 if (_codecCntrA == 0) {
525 fprintf(stdout, "\nTesting Delay ...\n");
526 TestDelay('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000527 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000528 // VAD TEST
529 TestSendVAD('A');
530 TestRegisteration('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000531 }
532 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000533}
534
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000535bool APITest::APIRunB() {
536 _apiEventB->Wait(50);
537 bool randomTest;
538 {
539 ReadLockScoped rl(_apiTestRWLock);
540 randomTest = _randomTest;
541 }
542 //_apiEventB->Wait(2000);
543 if (randomTest) {
544 RunTest('B');
545 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000546
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000547 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000548}
549
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000550void APITest::Perform() {
551 SetUp();
niklase@google.com470e71d2011-07-07 08:21:25 +0000552
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000553 //--- THREADS
554 // A
555 // PUSH
556 ThreadWrapper* myPushAudioThreadA = ThreadWrapper::CreateThread(
557 PushAudioThreadA, this, kNormalPriority, "PushAudioThreadA");
558 CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
559 // PULL
560 ThreadWrapper* myPullAudioThreadA = ThreadWrapper::CreateThread(
561 PullAudioThreadA, this, kNormalPriority, "PullAudioThreadA");
562 CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
563 // Process
564 ThreadWrapper* myProcessThreadA = ThreadWrapper::CreateThread(
565 ProcessThreadA, this, kNormalPriority, "ProcessThreadA");
566 CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
567 // API
568 ThreadWrapper* myAPIThreadA = ThreadWrapper::CreateThread(APIThreadA, this,
569 kNormalPriority,
570 "APIThreadA");
571 CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
572 // B
573 // PUSH
574 ThreadWrapper* myPushAudioThreadB = ThreadWrapper::CreateThread(
575 PushAudioThreadB, this, kNormalPriority, "PushAudioThreadB");
576 CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
577 // PULL
578 ThreadWrapper* myPullAudioThreadB = ThreadWrapper::CreateThread(
579 PullAudioThreadB, this, kNormalPriority, "PullAudioThreadB");
580 CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
581 // Process
582 ThreadWrapper* myProcessThreadB = ThreadWrapper::CreateThread(
583 ProcessThreadB, this, kNormalPriority, "ProcessThreadB");
584 CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
585 // API
586 ThreadWrapper* myAPIThreadB = ThreadWrapper::CreateThread(APIThreadB, this,
587 kNormalPriority,
588 "APIThreadB");
589 CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000590
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000591 //_apiEventA->StartTimer(true, 5000);
592 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000593
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000594 _processEventA->StartTimer(true, 10);
595 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000596
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000597 _pullEventA->StartTimer(true, 10);
598 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000599
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000600 _pushEventA->StartTimer(true, 10);
601 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000602
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000603 // Keep main thread waiting for sender/receiver
604 // threads to complete
605 EventWrapper* completeEvent = EventWrapper::Create();
606 uint64_t startTime = TickTime::MillisecondTimestamp();
607 uint64_t currentTime;
608 // Run test in 2 minutes (120000 ms).
609 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000610 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000611 //ReadLockScoped rl(_apiTestRWLock);
612 //fprintf(stderr, "\r%s", _movingDot);
613 }
614 //fflush(stderr);
615 completeEvent->Wait(50);
616 currentTime = TickTime::MillisecondTimestamp();
617 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000618
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000619 //completeEvent->Wait(0xFFFFFFFF);
620 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
621 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000622
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000623 myPushAudioThreadA->Stop();
624 myPullAudioThreadA->Stop();
625 myProcessThreadA->Stop();
626 myAPIThreadA->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000627
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000628 delete myPushAudioThreadA;
629 delete myPullAudioThreadA;
630 delete myProcessThreadA;
631 delete myAPIThreadA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000632
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000633 myPushAudioThreadB->Stop();
634 myPullAudioThreadB->Stop();
635 myProcessThreadB->Stop();
636 myAPIThreadB->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000637
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000638 delete myPushAudioThreadB;
639 delete myPullAudioThreadB;
640 delete myProcessThreadB;
641 delete myAPIThreadB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000642}
643
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000644void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000645
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000646 bool dtxEnabled;
647 bool vadEnabled;
648 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000649
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000650 if (side == 'A') {
651 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
652 _acmA->RegisterVADCallback(NULL);
653 _vadCallbackA->Reset();
654 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000655
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000656 if (!_randomTest) {
657 if (_verbose) {
658 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
659 vadEnabled ? "ON" : "OFF", (int) vadMode);
660 Wait(5000);
661 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
662 } else {
663 Wait(5000);
664 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
665 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
666 (int) vadMode, _channel_A2B->BitRate());
667 }
668 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000669 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000670
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000671 if (dtxEnabled != _sendDTXA) {
672 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000673 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000674 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
675 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
676 }
677 if ((vadMode != _sendVADModeA) && vadEnabled) {
678 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
679 }
680 } else {
681 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
682
683 _acmB->RegisterVADCallback(NULL);
684 _vadCallbackB->Reset();
685 _acmB->RegisterVADCallback(_vadCallbackB);
686
687 if (!_randomTest) {
688 if (_verbose) {
689 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
690 vadEnabled ? "ON" : "OFF", (int) vadMode);
691 Wait(5000);
692 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
693 } else {
694 Wait(5000);
695 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
696 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
697 (int) vadMode, _channel_B2A->BitRate());
698 }
699 _vadCallbackB->PrintFrameTypes();
700 }
701
702 if (dtxEnabled != _sendDTXB) {
703 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
704 }
705 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
706 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
707 }
708 if ((vadMode != _sendVADModeB) && vadEnabled) {
709 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
710 }
711 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000712}
713
714// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000715void APITest::TestDelay(char side) {
716 AudioCodingModule* myACM;
717 Channel* myChannel;
718 int32_t* myMinDelay;
719 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000720
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000721 uint32_t inTimestamp = 0;
722 uint32_t outTimestamp = 0;
723 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000724
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000725 double averageEstimDelay = 0;
726 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000727
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000728 CircularBuffer estimDelayCB(100);
729 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000730
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000731 if (side == 'A') {
732 myACM = _acmA;
733 myChannel = _channel_B2A;
734 myMinDelay = &_minDelayA;
735 } else {
736 myACM = _acmB;
737 myChannel = _channel_A2B;
738 myMinDelay = &_minDelayB;
739 }
740
741 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
742
743 inTimestamp = myChannel->LastInTimestamp();
744 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
745
746 if (!_randomTest) {
747 myEvent->StartTimer(true, 30);
748 int n = 0;
749 int settlePoint = 5000;
750 while (n < settlePoint + 400) {
751 myEvent->Wait(1000);
752
753 inTimestamp = myChannel->LastInTimestamp();
754 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
755
756 //std::cout << outTimestamp << std::endl << std::flush;
757 estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
758 / ((double) myACM->ReceiveFrequency() / 1000.0);
759
760 estimDelayCB.Update(estimDelay);
761
762 estimDelayCB.ArithMean(averageEstimDelay);
763 //printf("\n %6.1f \n", estimDelay);
764 //std::cout << " " << std::flush;
765
766 if (_verbose) {
767 fprintf(stdout,
768 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
769 *myMinDelay, averageDelay, averageEstimDelay);
770 std::cout << " " << std::flush;
771 }
772 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
773 settlePoint = n;
774 }
775 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000776 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000777 myEvent->StopTimer();
778 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000779
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000780 if ((!_verbose) && (!_randomTest)) {
781 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000782 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000783 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000784
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000785 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000786
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000787 ACMNetworkStatistics networkStat;
788 CHECK_ERROR_MT(myACM->NetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000789
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000790 if (!_randomTest) {
791 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
792 fprintf(stdout, "--------------------------------------\n");
793 fprintf(stdout, "buffer-size............. %d\n",
794 networkStat.currentBufferSize);
795 fprintf(stdout, "Preferred buffer-size... %d\n",
796 networkStat.preferredBufferSize);
797 fprintf(stdout, "Peaky jitter mode........%d\n",
798 networkStat.jitterPeaksFound);
799 fprintf(stdout, "packet-size rate........ %d\n",
800 networkStat.currentPacketLossRate);
801 fprintf(stdout, "discard rate............ %d\n",
802 networkStat.currentDiscardRate);
803 fprintf(stdout, "expand rate............. %d\n",
804 networkStat.currentExpandRate);
805 fprintf(stdout, "Preemptive rate......... %d\n",
806 networkStat.currentPreemptiveRate);
807 fprintf(stdout, "Accelerate rate......... %d\n",
808 networkStat.currentAccelerateRate);
809 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
810 fprintf(stdout, "Mean waiting time....... %d\n",
811 networkStat.meanWaitingTimeMs);
812 fprintf(stdout, "Median waiting time..... %d\n",
813 networkStat.medianWaitingTimeMs);
814 fprintf(stdout, "Min waiting time........ %d\n",
815 networkStat.minWaitingTimeMs);
816 fprintf(stdout, "Max waiting time........ %d\n",
817 networkStat.maxWaitingTimeMs);
818 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000819
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000820 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000821
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000822 if (!_randomTest) {
823 myEvent->Wait(500);
824 fprintf(stdout, "\n");
825 fprintf(stdout, "\n");
826 }
827 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000828}
829
830// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000831void APITest::TestRegisteration(char sendSide) {
832 AudioCodingModule* sendACM;
833 AudioCodingModule* receiveACM;
834 bool* thereIsDecoder;
835 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000836
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000837 if (!_randomTest) {
838 fprintf(stdout, "\n\n");
839 fprintf(stdout,
840 "---------------------------------------------------------\n");
841 fprintf(stdout, " Unregister/register Receive Codec\n");
842 fprintf(stdout,
843 "---------------------------------------------------------\n");
844 }
845
846 switch (sendSide) {
847 case 'A': {
848 sendACM = _acmA;
849 receiveACM = _acmB;
850 thereIsDecoder = &_thereIsDecoderB;
851 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000852 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000853 case 'B': {
854 sendACM = _acmB;
855 receiveACM = _acmA;
856 thereIsDecoder = &_thereIsDecoderA;
857 break;
858 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000859 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000860 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
861 sendSide);
862 exit(-1);
863 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000864
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000865 CodecInst myCodec;
866 if (sendACM->SendCodec(&myCodec) < 0) {
867 AudioCodingModule::Codec(_codecCntrA, &myCodec);
868 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000869
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000870 if (!_randomTest) {
871 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
872 fflush (stdout);
873 }
874 {
875 WriteLockScoped wl(_apiTestRWLock);
876 *thereIsDecoder = false;
877 }
878 //myEvent->Wait(20);
879 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
880 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000881
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000882 int currentPayload = myCodec.pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000883
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000884 if (!FixedPayloadTypeCodec(myCodec.plname)) {
885 int32_t i;
886 for (i = 0; i < 32; i++) {
887 if (!_payloadUsed[i]) {
888 if (!_randomTest) {
889 fprintf(stdout,
890 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000891 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000892 //myCodec.pltype = i + 96;
893 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
894 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
895 //myEvent->Wait(20);
896 //{
897 // WriteLockScoped wl(_apiTestRWLock);
898 // *thereIsDecoder = true;
899 //}
900 Wait(1000);
901
902 if (!_randomTest) {
903 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000904 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000905 //{
906 // WriteLockScoped wl(_apiTestRWLock);
907 // *thereIsDecoder = false;
908 //}
909 //myEvent->Wait(20);
910 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
911 Wait(1000);
912
913 myCodec.pltype = currentPayload;
914 if (!_randomTest) {
915 fprintf(stdout,
916 "Register receive codec with default Payload, AUDIO BACK.\n");
917 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000918 }
919 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000920 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000921 myEvent->Wait(20);
922 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000923 WriteLockScoped wl(_apiTestRWLock);
924 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000925 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000926 Wait(1000);
927
928 break;
929 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000930 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000931 if (i == 32) {
932 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
933 {
934 WriteLockScoped wl(_apiTestRWLock);
935 *thereIsDecoder = true;
936 }
937 }
938 } else {
939 if (!_randomTest) {
940 fprintf(stdout,
941 "Register receive codec with fixed Payload, AUDIO BACK.\n");
942 fflush (stdout);
943 }
944 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
945 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
946 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
947 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000948 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000949 WriteLockScoped wl(_apiTestRWLock);
950 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000951 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000952 }
953 delete myEvent;
954 if (!_randomTest) {
955 fprintf(stdout,
956 "---------------------------------------------------------\n");
957 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000958}
959
960// Playout Mode, background noise mode.
961// Receiver Frequency, playout frequency.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000962void APITest::TestPlayout(char receiveSide) {
963 AudioCodingModule* receiveACM;
964 AudioPlayoutMode* playoutMode = NULL;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000965 switch (receiveSide) {
966 case 'A': {
967 receiveACM = _acmA;
968 playoutMode = &_playoutModeA;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000969 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000970 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000971 case 'B': {
972 receiveACM = _acmB;
973 playoutMode = &_playoutModeB;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000974 break;
975 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000976 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000977 receiveACM = _acmA;
978 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000979
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000980 int32_t receiveFreqHz = receiveACM->ReceiveFrequency();
981 int32_t playoutFreqHz = receiveACM->PlayoutFrequency();
982
983 CHECK_ERROR_MT(receiveFreqHz);
984 CHECK_ERROR_MT(playoutFreqHz);
985
niklase@google.com470e71d2011-07-07 08:21:25 +0000986
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000987 char playoutString[25];
988 switch (*playoutMode) {
989 case voice: {
990 *playoutMode = fax;
991 strncpy(playoutString, "FAX", 25);
992 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000993 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000994 case fax: {
995 *playoutMode = streaming;
996 strncpy(playoutString, "Streaming", 25);
997 break;
998 }
999 case streaming: {
1000 *playoutMode = voice;
1001 strncpy(playoutString, "Voice", 25);
1002 break;
1003 }
1004 default:
1005 *playoutMode = voice;
1006 strncpy(playoutString, "Voice", 25);
1007 }
1008 CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
1009 playoutString[24] = '\0';
1010
1011 if (!_randomTest) {
1012 fprintf(stdout, "\n");
1013 fprintf(stdout, "In Side %c\n", receiveSide);
1014 fprintf(stdout, "---------------------------------\n");
1015 fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
1016 fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
1017 fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001018 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001019}
1020
1021// set/get receiver VAD status & mode.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001022void APITest::TestSendVAD(char side) {
1023 if (_randomTest) {
1024 return;
1025 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001026
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001027 bool* vad;
1028 bool* dtx;
1029 ACMVADMode* mode;
1030 Channel* myChannel;
1031 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +00001032
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001033 CodecInst myCodec;
1034 if (!_randomTest) {
1035 fprintf(stdout, "\n\n");
1036 fprintf(stdout, "-----------------------------------------------\n");
1037 fprintf(stdout, " Test VAD API\n");
1038 fprintf(stdout, "-----------------------------------------------\n");
1039 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001040
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001041 if (side == 'A') {
1042 AudioCodingModule::Codec(_codecCntrA, &myCodec);
1043 vad = &_sendVADA;
1044 dtx = &_sendDTXA;
1045 mode = &_sendVADModeA;
1046 myChannel = _channel_A2B;
1047 myACM = _acmA;
1048 } else {
1049 AudioCodingModule::Codec(_codecCntrB, &myCodec);
1050 vad = &_sendVADB;
1051 dtx = &_sendDTXB;
1052 mode = &_sendVADModeB;
1053 myChannel = _channel_B2A;
1054 myACM = _acmB;
1055 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001056
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001057 CheckVADStatus(side);
1058 if (!_randomTest) {
1059 fprintf(stdout, "\n\n");
1060 }
1061
1062 switch (*mode) {
1063 case VADNormal:
1064 *vad = true;
1065 *dtx = true;
1066 *mode = VADAggr;
1067 break;
1068 case VADLowBitrate:
1069 *vad = true;
1070 *dtx = true;
1071 *mode = VADVeryAggr;
1072 break;
1073 case VADAggr:
1074 *vad = true;
1075 *dtx = true;
1076 *mode = VADLowBitrate;
1077 break;
1078 case VADVeryAggr:
1079 *vad = false;
1080 *dtx = false;
1081 *mode = VADNormal;
1082 break;
1083 default:
1084 *mode = VADNormal;
1085 }
1086
1087 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
1088
1089 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1090 myChannel->ResetStats();
1091
1092 CheckVADStatus(side);
1093 if (!_randomTest) {
1094 fprintf(stdout, "\n");
1095 fprintf(stdout, "-----------------------------------------------\n");
1096 }
1097
1098 // Fault Test
1099 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
1100 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +00001101
1102}
1103
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001104void APITest::CurrentCodec(char side) {
1105 CodecInst myCodec;
1106 if (side == 'A') {
1107 _acmA->SendCodec(&myCodec);
1108 } else {
1109 _acmB->SendCodec(&myCodec);
1110 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001111
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001112 if (!_randomTest) {
1113 fprintf(stdout, "\n\n");
1114 fprintf(stdout, "Send codec in Side A\n");
1115 fprintf(stdout, "----------------------------\n");
1116 fprintf(stdout, "Name................. %s\n", myCodec.plname);
1117 fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
1118 fprintf(stdout, "Rate................. %d\n", myCodec.rate);
1119 fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
1120 fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
1121 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001122
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001123 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001124}
1125
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001126void APITest::ChangeCodec(char side) {
1127 CodecInst myCodec;
1128 AudioCodingModule* myACM;
1129 uint8_t* codecCntr;
1130 bool* thereIsEncoder;
1131 bool* vad;
1132 bool* dtx;
1133 ACMVADMode* mode;
1134 Channel* myChannel;
1135 // Reset and Wait
1136 if (!_randomTest) {
1137 fprintf(stdout, "Reset Encoder Side A \n");
1138 }
1139 if (side == 'A') {
1140 myACM = _acmA;
1141 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001142 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001143 WriteLockScoped wl(_apiTestRWLock);
1144 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001145 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001146 vad = &_sendVADA;
1147 dtx = &_sendDTXA;
1148 mode = &_sendVADModeA;
1149 myChannel = _channel_A2B;
1150 } else {
1151 myACM = _acmB;
1152 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001153 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001154 WriteLockScoped wl(_apiTestRWLock);
1155 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001156 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001157 vad = &_sendVADB;
1158 dtx = &_sendDTXB;
1159 mode = &_sendVADModeB;
1160 myChannel = _channel_B2A;
1161 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001162
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001163 myACM->ResetEncoder();
1164 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001165
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001166 // Register the next codec
1167 do {
1168 *codecCntr =
1169 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1170 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001171
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001172 if (*codecCntr == 0) {
1173 //printf("Initialize Sender Side A \n");
1174 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001175 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001176 *thereIsEncoder = false;
1177 }
1178 CHECK_ERROR_MT(myACM->InitializeSender());
1179 Wait(1000);
1180
1181 // After Initialization CN is lost, re-register them
1182 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1183 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1184 }
1185 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1186 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1187 }
1188 // VAD & DTX are disabled after initialization
1189 *vad = false;
1190 *dtx = false;
1191 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001192 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001193
1194 AudioCodingModule::Codec(*codecCntr, &myCodec);
1195 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1196 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1197 || !STR_CASE_CMP(myCodec.plname, "RED"));
1198
1199 if (!_randomTest) {
1200 fprintf(stdout,"\n=====================================================\n");
1201 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1202 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1203 }
1204 //std::cout<< std::flush;
1205
1206 // NO DTX for supe-wideband codec at this point
1207 if (myCodec.plfreq == 32000) {
1208 *dtx = false;
1209 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1210
1211 }
1212
1213 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1214 myChannel->ResetStats();
1215 {
1216 WriteLockScoped wl(_apiTestRWLock);
1217 *thereIsEncoder = true;
1218 }
1219 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001220}
1221
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001222} // namespace webrtc