blob: cf213433d86ad483430e475d7578d3bb53b43f0a [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) { \
41 unsigned int i; \
42 (myThread)->Start(i); \
43 } else { \
44 ADD_FAILURE() << S; \
45 }
niklase@google.com470e71d2011-07-07 08:21:25 +000046
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000047void APITest::Wait(uint32_t waitLengthMs) {
48 if (_randomTest) {
49 return;
50 } else {
51 EventWrapper* myEvent = EventWrapper::Create();
52 myEvent->Wait(waitLengthMs);
53 delete myEvent;
54 return;
55 }
niklase@google.com470e71d2011-07-07 08:21:25 +000056}
57
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000058APITest::APITest(const Config& config)
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +000059 : _acmA(AudioCodingModule::Create(1)),
60 _acmB(AudioCodingModule::Create(2)),
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000061 _channel_A2B(NULL),
62 _channel_B2A(NULL),
63 _writeToFile(true),
64 _pullEventA(NULL),
65 _pushEventA(NULL),
66 _processEventA(NULL),
67 _apiEventA(NULL),
68 _pullEventB(NULL),
69 _pushEventB(NULL),
70 _processEventB(NULL),
71 _apiEventB(NULL),
72 _codecCntrA(0),
73 _codecCntrB(0),
74 _thereIsEncoderA(false),
75 _thereIsEncoderB(false),
76 _thereIsDecoderA(false),
77 _thereIsDecoderB(false),
78 _sendVADA(false),
79 _sendDTXA(false),
80 _sendVADModeA(VADNormal),
81 _sendVADB(false),
82 _sendDTXB(false),
83 _sendVADModeB(VADNormal),
84 _minDelayA(0),
85 _minDelayB(0),
86 _dotPositionA(0),
87 _dotMoveDirectionA(1),
88 _dotPositionB(39),
89 _dotMoveDirectionB(-1),
90 _dtmfCallback(NULL),
91 _vadCallbackA(NULL),
92 _vadCallbackB(NULL),
93 _apiTestRWLock(*RWLockWrapper::CreateRWLock()),
94 _randomTest(false),
95 _testNumA(0),
96 _testNumB(1) {
97 int n;
98 for (n = 0; n < 32; n++) {
99 _payloadUsed[n] = false;
100 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000101
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000102 _movingDot[40] = '\0';
niklase@google.com470e71d2011-07-07 08:21:25 +0000103
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000104 for (int n = 0; n < 40; n++) {
105 _movingDot[n] = ' ';
106 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000107}
108
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000109APITest::~APITest() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000110 DELETE_POINTER(_channel_A2B);
111 DELETE_POINTER(_channel_B2A);
niklase@google.com470e71d2011-07-07 08:21:25 +0000112
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000113 DELETE_POINTER(_pushEventA);
114 DELETE_POINTER(_pullEventA);
115 DELETE_POINTER(_processEventA);
116 DELETE_POINTER(_apiEventA);
niklase@google.com470e71d2011-07-07 08:21:25 +0000117
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000118 DELETE_POINTER(_pushEventB);
119 DELETE_POINTER(_pullEventB);
120 DELETE_POINTER(_processEventB);
121 DELETE_POINTER(_apiEventB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000122
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000123 _inFileA.Close();
124 _outFileA.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000125
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000126 _inFileB.Close();
127 _outFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000128
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000129 DELETE_POINTER(_dtmfCallback);
130 DELETE_POINTER(_vadCallbackA);
131 DELETE_POINTER(_vadCallbackB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000132
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000133 delete &_apiTestRWLock;
niklase@google.com470e71d2011-07-07 08:21:25 +0000134}
135
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000136int16_t APITest::SetUp() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000137 CodecInst dummyCodec;
138 int lastPayloadType = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000139
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000140 int16_t numCodecs = _acmA->NumberOfCodecs();
141 for (uint8_t n = 0; n < numCodecs; n++) {
142 AudioCodingModule::Codec(n, &dummyCodec);
143 if ((STR_CASE_CMP(dummyCodec.plname, "CN") == 0)
144 && (dummyCodec.plfreq == 32000)) {
145 continue;
niklase@google.com470e71d2011-07-07 08:21:25 +0000146 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000147
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000148 printf("Register Receive Codec %s ", dummyCodec.plname);
niklase@google.com470e71d2011-07-07 08:21:25 +0000149
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000150 if ((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
151 // Check registration with an already occupied payload type
152 int currentPayloadType = dummyCodec.pltype;
153 dummyCodec.pltype = 97; //lastPayloadType;
154 CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
155 dummyCodec.pltype = currentPayloadType;
156 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000157
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000158 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
159 // test if re-registration works;
160 CodecInst nextCodec;
161 int currentPayloadType = dummyCodec.pltype;
162 AudioCodingModule::Codec(n + 1, &nextCodec);
163 dummyCodec.pltype = nextCodec.pltype;
164 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
165 _acmB->RegisterReceiveCodec(dummyCodec);
166 }
167 dummyCodec.pltype = currentPayloadType;
168 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000169
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000170 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
171 // test if un-registration works;
172 CodecInst nextCodec;
173 AudioCodingModule::Codec(n + 1, &nextCodec);
174 nextCodec.pltype = dummyCodec.pltype;
175 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
176 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
177 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
178 }
179 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000180
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000181 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
182 printf(" side A done!");
183 CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
184 printf(" side B done!\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000185
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000186 if (!strcmp(dummyCodec.plname, "CN")) {
187 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
188 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
189 }
190 lastPayloadType = dummyCodec.pltype;
191 if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
192 _payloadUsed[lastPayloadType - 96] = true;
193 }
194 }
195 _thereIsDecoderA = true;
196 _thereIsDecoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000197
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000198 // Register Send Codec
199 AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
200 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
201 _thereIsEncoderA = true;
202 //
203 AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
204 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
205 _thereIsEncoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000206
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000207 uint16_t frequencyHz;
niklase@google.com470e71d2011-07-07 08:21:25 +0000208
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000209 printf("\n\nAPI Test\n");
210 printf("========\n");
211 printf("Hit enter to accept the default values indicated in []\n\n");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000212
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000213 //--- Input A
214 std::string file_name = webrtc::test::ResourcePath(
215 "audio_coding/testfile32kHz", "pcm");
216 frequencyHz = 32000;
217 printf("Enter input file at side A [%s]: ", file_name.c_str());
218 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
219 _inFileA.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000220
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000221 //--- Output A
222 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
223 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
224 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
225 _outFileA.Open(out_file_a, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000226
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000227 //--- Input B
228 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
229 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
230 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
231 _inFileB.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000232
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000233 //--- Output B
234 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
235 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
236 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
237 _outFileB.Open(out_file_b, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000238
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000239 //--- Set A-to-B channel
240 _channel_A2B = new Channel(2);
241 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000242 _channel_A2B->RegisterReceiverACM(_acmB.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000243
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000244 //--- Set B-to-A channel
245 _channel_B2A = new Channel(1);
246 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000247 _channel_B2A->RegisterReceiverACM(_acmA.get());
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +0000248
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000249 //--- EVENT TIMERS
250 // A
251 _pullEventA = EventWrapper::Create();
252 _pushEventA = EventWrapper::Create();
253 _processEventA = EventWrapper::Create();
254 _apiEventA = EventWrapper::Create();
255 // B
256 _pullEventB = EventWrapper::Create();
257 _pushEventB = EventWrapper::Create();
258 _processEventB = EventWrapper::Create();
259 _apiEventB = EventWrapper::Create();
260
261 //--- I/O params
262 // A
263 _outFreqHzA = _outFileA.SamplingFrequency();
264 // B
265 _outFreqHzB = _outFileB.SamplingFrequency();
266
267 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
268
269 char print[11];
270
271 // Create a trace file.
272 Trace::CreateTrace();
273 Trace::SetTraceFile(
274 (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
275
276 printf("\nRandom Test (y/n)?");
277 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
278 print[10] = '\0';
279 if (strstr(print, "y") != NULL) {
280 _randomTest = true;
281 _verbose = false;
282 _writeToFile = false;
283 } else {
284 _randomTest = false;
285 printf("\nPrint Tests (y/n)? ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000286 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000287 print[10] = '\0';
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000288 if (strstr(print, "y") == NULL) {
289 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
290 _verbose = false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000291 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000292 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000293
294#ifdef WEBRTC_DTMF_DETECTION
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000295 _dtmfCallback = new DTMFDetector;
niklase@google.com470e71d2011-07-07 08:21:25 +0000296#endif
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000297 _vadCallbackA = new VADCallback;
298 _vadCallbackB = new VADCallback;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000299
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000300 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000301}
302
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000303bool APITest::PushAudioThreadA(void* obj) {
304 return static_cast<APITest*>(obj)->PushAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000305}
306
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000307bool APITest::PushAudioThreadB(void* obj) {
308 return static_cast<APITest*>(obj)->PushAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000309}
310
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000311bool APITest::PullAudioThreadA(void* obj) {
312 return static_cast<APITest*>(obj)->PullAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000313}
314
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000315bool APITest::PullAudioThreadB(void* obj) {
316 return static_cast<APITest*>(obj)->PullAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000317}
318
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000319bool APITest::ProcessThreadA(void* obj) {
320 return static_cast<APITest*>(obj)->ProcessRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000321}
322
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000323bool APITest::ProcessThreadB(void* obj) {
324 return static_cast<APITest*>(obj)->ProcessRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000325}
326
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000327bool APITest::APIThreadA(void* obj) {
328 return static_cast<APITest*>(obj)->APIRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000329}
330
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000331bool APITest::APIThreadB(void* obj) {
332 return static_cast<APITest*>(obj)->APIRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000333}
334
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000335bool APITest::PullAudioRunA() {
336 _pullEventA->Wait(100);
337 AudioFrame audioFrame;
338 if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame) < 0) {
339 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000341 ReadLockScoped rl(_apiTestRWLock);
342 thereIsDecoder = _thereIsDecoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000344 if (thereIsDecoder) {
345 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000347 } else {
348 if (_writeToFile) {
349 _outFileA.Write10MsData(audioFrame);
350 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000351 }
352 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000353}
354
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000355bool APITest::PullAudioRunB() {
356 _pullEventB->Wait(100);
357 AudioFrame audioFrame;
358 if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame) < 0) {
359 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000360 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000361 ReadLockScoped rl(_apiTestRWLock);
362 thereIsDecoder = _thereIsDecoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000363 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000364 if (thereIsDecoder) {
365 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
366 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000367 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000368 } else {
369 if (_writeToFile) {
370 _outFileB.Write10MsData(audioFrame);
371 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000372 }
373 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000374}
375
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000376bool APITest::PushAudioRunA() {
377 _pushEventA->Wait(100);
378 AudioFrame audioFrame;
379 _inFileA.Read10MsData(audioFrame);
380 if (_acmA->Add10MsData(audioFrame) < 0) {
381 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000382 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000383 ReadLockScoped rl(_apiTestRWLock);
384 thereIsEncoder = _thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000385 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000386 if (thereIsEncoder) {
387 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
388 }
389 }
390 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000391}
392
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000393bool APITest::PushAudioRunB() {
394 _pushEventB->Wait(100);
395 AudioFrame audioFrame;
396 _inFileB.Read10MsData(audioFrame);
397 if (_acmB->Add10MsData(audioFrame) < 0) {
398 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000399 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000400 ReadLockScoped rl(_apiTestRWLock);
401 thereIsEncoder = _thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000402 }
403
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000404 if (thereIsEncoder) {
405 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
406 }
407 }
408
409 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000410}
411
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000412bool APITest::ProcessRunA() {
413 _processEventA->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000414 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000415}
416
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000417bool APITest::ProcessRunB() {
418 _processEventB->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000419 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000420}
421
422/*/
423 *
424 * In side A we test the APIs which are related to sender Side.
425 *
426/*/
427
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000428void APITest::RunTest(char thread) {
429 int testNum;
430 {
431 WriteLockScoped cs(_apiTestRWLock);
432 if (thread == 'A') {
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +0000433 _testNumA = (_testNumB + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000434 testNum = _testNumA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000435
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000436 _movingDot[_dotPositionA] = ' ';
437 if (_dotPositionA == 0) {
438 _dotMoveDirectionA = 1;
439 }
440 if (_dotPositionA == 19) {
441 _dotMoveDirectionA = -1;
442 }
443 _dotPositionA += _dotMoveDirectionA;
444 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
445 } else {
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +0000446 _testNumB = (_testNumA + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000447 testNum = _testNumB;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000448
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000449 _movingDot[_dotPositionB] = ' ';
450 if (_dotPositionB == 20) {
451 _dotMoveDirectionB = 1;
452 }
453 if (_dotPositionB == 39) {
454 _dotMoveDirectionB = -1;
455 }
456 _dotPositionB += _dotMoveDirectionB;
457 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
niklase@google.com470e71d2011-07-07 08:21:25 +0000458 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000459 //fprintf(stderr, "%c: %d \n", thread, testNum);
460 //fflush(stderr);
461 }
462 switch (testNum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000463 case 0:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000464 CurrentCodec('A');
465 ChangeCodec('A');
466 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000467 case 1:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000468 TestPlayout('B');
469 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000470 case 2:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000471 if (!_randomTest) {
472 fprintf(stdout, "\nTesting Delay ...\n");
473 }
474 TestDelay('A');
475 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000476 case 3:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000477 TestSendVAD('A');
478 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000479 case 4:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000480 TestRegisteration('A');
481 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000482 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000483 fprintf(stderr, "Wrong Test Number\n");
marpan@webrtc.org4765ca52014-11-03 20:10:26 +0000484 getc(stdin);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000485 exit(1);
486 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000487}
488
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000489bool APITest::APIRunA() {
490 _apiEventA->Wait(50);
niklase@google.com470e71d2011-07-07 08:21:25 +0000491
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000492 bool randomTest;
493 {
494 ReadLockScoped rl(_apiTestRWLock);
495 randomTest = _randomTest;
496 }
497 if (randomTest) {
498 RunTest('A');
499 } else {
500 CurrentCodec('A');
501 ChangeCodec('A');
502 TestPlayout('B');
503 if (_codecCntrA == 0) {
504 fprintf(stdout, "\nTesting Delay ...\n");
505 TestDelay('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000506 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000507 // VAD TEST
508 TestSendVAD('A');
509 TestRegisteration('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000510 }
511 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000512}
513
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000514bool APITest::APIRunB() {
515 _apiEventB->Wait(50);
516 bool randomTest;
517 {
518 ReadLockScoped rl(_apiTestRWLock);
519 randomTest = _randomTest;
520 }
521 //_apiEventB->Wait(2000);
522 if (randomTest) {
523 RunTest('B');
524 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000525
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000526 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000527}
528
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000529void APITest::Perform() {
530 SetUp();
niklase@google.com470e71d2011-07-07 08:21:25 +0000531
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000532 //--- THREADS
533 // A
534 // PUSH
535 ThreadWrapper* myPushAudioThreadA = ThreadWrapper::CreateThread(
536 PushAudioThreadA, this, kNormalPriority, "PushAudioThreadA");
537 CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
538 // PULL
539 ThreadWrapper* myPullAudioThreadA = ThreadWrapper::CreateThread(
540 PullAudioThreadA, this, kNormalPriority, "PullAudioThreadA");
541 CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
542 // Process
543 ThreadWrapper* myProcessThreadA = ThreadWrapper::CreateThread(
544 ProcessThreadA, this, kNormalPriority, "ProcessThreadA");
545 CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
546 // API
547 ThreadWrapper* myAPIThreadA = ThreadWrapper::CreateThread(APIThreadA, this,
548 kNormalPriority,
549 "APIThreadA");
550 CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
551 // B
552 // PUSH
553 ThreadWrapper* myPushAudioThreadB = ThreadWrapper::CreateThread(
554 PushAudioThreadB, this, kNormalPriority, "PushAudioThreadB");
555 CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
556 // PULL
557 ThreadWrapper* myPullAudioThreadB = ThreadWrapper::CreateThread(
558 PullAudioThreadB, this, kNormalPriority, "PullAudioThreadB");
559 CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
560 // Process
561 ThreadWrapper* myProcessThreadB = ThreadWrapper::CreateThread(
562 ProcessThreadB, this, kNormalPriority, "ProcessThreadB");
563 CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
564 // API
565 ThreadWrapper* myAPIThreadB = ThreadWrapper::CreateThread(APIThreadB, this,
566 kNormalPriority,
567 "APIThreadB");
568 CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000569
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000570 //_apiEventA->StartTimer(true, 5000);
571 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000572
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000573 _processEventA->StartTimer(true, 10);
574 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000575
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000576 _pullEventA->StartTimer(true, 10);
577 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000578
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000579 _pushEventA->StartTimer(true, 10);
580 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000581
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000582 // Keep main thread waiting for sender/receiver
583 // threads to complete
584 EventWrapper* completeEvent = EventWrapper::Create();
585 uint64_t startTime = TickTime::MillisecondTimestamp();
586 uint64_t currentTime;
587 // Run test in 2 minutes (120000 ms).
588 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000589 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000590 //ReadLockScoped rl(_apiTestRWLock);
591 //fprintf(stderr, "\r%s", _movingDot);
592 }
593 //fflush(stderr);
594 completeEvent->Wait(50);
595 currentTime = TickTime::MillisecondTimestamp();
596 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000597
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000598 //completeEvent->Wait(0xFFFFFFFF);
599 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
600 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000601
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000602 myPushAudioThreadA->Stop();
603 myPullAudioThreadA->Stop();
604 myProcessThreadA->Stop();
605 myAPIThreadA->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000606
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000607 delete myPushAudioThreadA;
608 delete myPullAudioThreadA;
609 delete myProcessThreadA;
610 delete myAPIThreadA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000611
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000612 myPushAudioThreadB->Stop();
613 myPullAudioThreadB->Stop();
614 myProcessThreadB->Stop();
615 myAPIThreadB->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000616
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000617 delete myPushAudioThreadB;
618 delete myPullAudioThreadB;
619 delete myProcessThreadB;
620 delete myAPIThreadB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000621}
622
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000623void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000624
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000625 bool dtxEnabled;
626 bool vadEnabled;
627 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000628
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000629 if (side == 'A') {
630 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
631 _acmA->RegisterVADCallback(NULL);
632 _vadCallbackA->Reset();
633 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000634
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000635 if (!_randomTest) {
636 if (_verbose) {
637 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
638 vadEnabled ? "ON" : "OFF", (int) vadMode);
639 Wait(5000);
640 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
641 } else {
642 Wait(5000);
643 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
644 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
645 (int) vadMode, _channel_A2B->BitRate());
646 }
647 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000648 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000649
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000650 if (dtxEnabled != _sendDTXA) {
651 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000652 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000653 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
654 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
655 }
656 if ((vadMode != _sendVADModeA) && vadEnabled) {
657 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
658 }
659 } else {
660 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
661
662 _acmB->RegisterVADCallback(NULL);
663 _vadCallbackB->Reset();
664 _acmB->RegisterVADCallback(_vadCallbackB);
665
666 if (!_randomTest) {
667 if (_verbose) {
668 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
669 vadEnabled ? "ON" : "OFF", (int) vadMode);
670 Wait(5000);
671 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
672 } else {
673 Wait(5000);
674 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
675 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
676 (int) vadMode, _channel_B2A->BitRate());
677 }
678 _vadCallbackB->PrintFrameTypes();
679 }
680
681 if (dtxEnabled != _sendDTXB) {
682 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
683 }
684 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
685 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
686 }
687 if ((vadMode != _sendVADModeB) && vadEnabled) {
688 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
689 }
690 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000691}
692
693// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000694void APITest::TestDelay(char side) {
695 AudioCodingModule* myACM;
696 Channel* myChannel;
697 int32_t* myMinDelay;
698 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000699
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000700 uint32_t inTimestamp = 0;
701 uint32_t outTimestamp = 0;
702 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000703
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000704 double averageEstimDelay = 0;
705 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000706
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000707 CircularBuffer estimDelayCB(100);
708 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000709
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000710 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000711 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000712 myChannel = _channel_B2A;
713 myMinDelay = &_minDelayA;
714 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000715 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000716 myChannel = _channel_A2B;
717 myMinDelay = &_minDelayB;
718 }
719
720 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
721
722 inTimestamp = myChannel->LastInTimestamp();
723 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
724
725 if (!_randomTest) {
726 myEvent->StartTimer(true, 30);
727 int n = 0;
728 int settlePoint = 5000;
729 while (n < settlePoint + 400) {
730 myEvent->Wait(1000);
731
732 inTimestamp = myChannel->LastInTimestamp();
733 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
734
735 //std::cout << outTimestamp << std::endl << std::flush;
736 estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
737 / ((double) myACM->ReceiveFrequency() / 1000.0);
738
739 estimDelayCB.Update(estimDelay);
740
741 estimDelayCB.ArithMean(averageEstimDelay);
742 //printf("\n %6.1f \n", estimDelay);
743 //std::cout << " " << std::flush;
744
745 if (_verbose) {
746 fprintf(stdout,
747 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
748 *myMinDelay, averageDelay, averageEstimDelay);
749 std::cout << " " << std::flush;
750 }
751 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
752 settlePoint = n;
753 }
754 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000755 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000756 myEvent->StopTimer();
757 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000758
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000759 if ((!_verbose) && (!_randomTest)) {
760 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000761 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000762 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000763
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000764 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000765
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000766 NetworkStatistics networkStat;
767 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000768
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000769 if (!_randomTest) {
770 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
771 fprintf(stdout, "--------------------------------------\n");
772 fprintf(stdout, "buffer-size............. %d\n",
773 networkStat.currentBufferSize);
774 fprintf(stdout, "Preferred buffer-size... %d\n",
775 networkStat.preferredBufferSize);
776 fprintf(stdout, "Peaky jitter mode........%d\n",
777 networkStat.jitterPeaksFound);
778 fprintf(stdout, "packet-size rate........ %d\n",
779 networkStat.currentPacketLossRate);
780 fprintf(stdout, "discard rate............ %d\n",
781 networkStat.currentDiscardRate);
782 fprintf(stdout, "expand rate............. %d\n",
783 networkStat.currentExpandRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000784 fprintf(stdout, "speech expand rate...... %d\n",
785 networkStat.currentSpeechExpandRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000786 fprintf(stdout, "Preemptive rate......... %d\n",
787 networkStat.currentPreemptiveRate);
788 fprintf(stdout, "Accelerate rate......... %d\n",
789 networkStat.currentAccelerateRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000790 fprintf(stdout, "Secondary decoded rate.. %d\n",
791 networkStat.currentSecondaryDecodedRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000792 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
793 fprintf(stdout, "Mean waiting time....... %d\n",
794 networkStat.meanWaitingTimeMs);
795 fprintf(stdout, "Median waiting time..... %d\n",
796 networkStat.medianWaitingTimeMs);
797 fprintf(stdout, "Min waiting time........ %d\n",
798 networkStat.minWaitingTimeMs);
799 fprintf(stdout, "Max waiting time........ %d\n",
800 networkStat.maxWaitingTimeMs);
801 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000802
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000803 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000804
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000805 if (!_randomTest) {
806 myEvent->Wait(500);
807 fprintf(stdout, "\n");
808 fprintf(stdout, "\n");
809 }
810 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000811}
812
813// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000814void APITest::TestRegisteration(char sendSide) {
815 AudioCodingModule* sendACM;
816 AudioCodingModule* receiveACM;
817 bool* thereIsDecoder;
818 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000819
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000820 if (!_randomTest) {
821 fprintf(stdout, "\n\n");
822 fprintf(stdout,
823 "---------------------------------------------------------\n");
824 fprintf(stdout, " Unregister/register Receive Codec\n");
825 fprintf(stdout,
826 "---------------------------------------------------------\n");
827 }
828
829 switch (sendSide) {
830 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000831 sendACM = _acmA.get();
832 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000833 thereIsDecoder = &_thereIsDecoderB;
834 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000835 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000836 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000837 sendACM = _acmB.get();
838 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000839 thereIsDecoder = &_thereIsDecoderA;
840 break;
841 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000842 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000843 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
844 sendSide);
845 exit(-1);
846 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000847
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000848 CodecInst myCodec;
849 if (sendACM->SendCodec(&myCodec) < 0) {
850 AudioCodingModule::Codec(_codecCntrA, &myCodec);
851 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000852
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000853 if (!_randomTest) {
854 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
855 fflush (stdout);
856 }
857 {
858 WriteLockScoped wl(_apiTestRWLock);
859 *thereIsDecoder = false;
860 }
861 //myEvent->Wait(20);
862 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
863 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000864
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000865 int currentPayload = myCodec.pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000866
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000867 if (!FixedPayloadTypeCodec(myCodec.plname)) {
868 int32_t i;
869 for (i = 0; i < 32; i++) {
870 if (!_payloadUsed[i]) {
871 if (!_randomTest) {
872 fprintf(stdout,
873 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000874 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000875 //myCodec.pltype = i + 96;
876 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
877 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
878 //myEvent->Wait(20);
879 //{
880 // WriteLockScoped wl(_apiTestRWLock);
881 // *thereIsDecoder = true;
882 //}
883 Wait(1000);
884
885 if (!_randomTest) {
886 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000887 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000888 //{
889 // WriteLockScoped wl(_apiTestRWLock);
890 // *thereIsDecoder = false;
891 //}
892 //myEvent->Wait(20);
893 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
894 Wait(1000);
895
896 myCodec.pltype = currentPayload;
897 if (!_randomTest) {
898 fprintf(stdout,
899 "Register receive codec with default Payload, AUDIO BACK.\n");
900 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000901 }
902 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000903 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000904 myEvent->Wait(20);
905 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000906 WriteLockScoped wl(_apiTestRWLock);
907 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000908 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000909 Wait(1000);
910
911 break;
912 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000913 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000914 if (i == 32) {
915 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
916 {
917 WriteLockScoped wl(_apiTestRWLock);
918 *thereIsDecoder = true;
919 }
920 }
921 } else {
922 if (!_randomTest) {
923 fprintf(stdout,
924 "Register receive codec with fixed Payload, AUDIO BACK.\n");
925 fflush (stdout);
926 }
927 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
928 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
929 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
930 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000931 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000932 WriteLockScoped wl(_apiTestRWLock);
933 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000934 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000935 }
936 delete myEvent;
937 if (!_randomTest) {
938 fprintf(stdout,
939 "---------------------------------------------------------\n");
940 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000941}
942
943// Playout Mode, background noise mode.
944// Receiver Frequency, playout frequency.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000945void APITest::TestPlayout(char receiveSide) {
946 AudioCodingModule* receiveACM;
947 AudioPlayoutMode* playoutMode = NULL;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000948 switch (receiveSide) {
949 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000950 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000951 playoutMode = &_playoutModeA;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000952 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000953 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000954 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000955 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000956 playoutMode = &_playoutModeB;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000957 break;
958 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000959 default:
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000960 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000961 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000962
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000963 int32_t receiveFreqHz = receiveACM->ReceiveFrequency();
964 int32_t playoutFreqHz = receiveACM->PlayoutFrequency();
965
966 CHECK_ERROR_MT(receiveFreqHz);
967 CHECK_ERROR_MT(playoutFreqHz);
968
niklase@google.com470e71d2011-07-07 08:21:25 +0000969
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000970 char playoutString[25];
971 switch (*playoutMode) {
972 case voice: {
973 *playoutMode = fax;
974 strncpy(playoutString, "FAX", 25);
975 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000976 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000977 case fax: {
978 *playoutMode = streaming;
979 strncpy(playoutString, "Streaming", 25);
980 break;
981 }
982 case streaming: {
983 *playoutMode = voice;
984 strncpy(playoutString, "Voice", 25);
985 break;
986 }
987 default:
988 *playoutMode = voice;
989 strncpy(playoutString, "Voice", 25);
990 }
991 CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
992 playoutString[24] = '\0';
993
994 if (!_randomTest) {
995 fprintf(stdout, "\n");
996 fprintf(stdout, "In Side %c\n", receiveSide);
997 fprintf(stdout, "---------------------------------\n");
998 fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
999 fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
1000 fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001001 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001002}
1003
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001004void APITest::TestSendVAD(char side) {
1005 if (_randomTest) {
1006 return;
1007 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001008
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001009 bool* vad;
1010 bool* dtx;
1011 ACMVADMode* mode;
1012 Channel* myChannel;
1013 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +00001014
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001015 CodecInst myCodec;
1016 if (!_randomTest) {
1017 fprintf(stdout, "\n\n");
1018 fprintf(stdout, "-----------------------------------------------\n");
1019 fprintf(stdout, " Test VAD API\n");
1020 fprintf(stdout, "-----------------------------------------------\n");
1021 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001022
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001023 if (side == 'A') {
1024 AudioCodingModule::Codec(_codecCntrA, &myCodec);
1025 vad = &_sendVADA;
1026 dtx = &_sendDTXA;
1027 mode = &_sendVADModeA;
1028 myChannel = _channel_A2B;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001029 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001030 } else {
1031 AudioCodingModule::Codec(_codecCntrB, &myCodec);
1032 vad = &_sendVADB;
1033 dtx = &_sendDTXB;
1034 mode = &_sendVADModeB;
1035 myChannel = _channel_B2A;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001036 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001037 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001038
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001039 CheckVADStatus(side);
1040 if (!_randomTest) {
1041 fprintf(stdout, "\n\n");
1042 }
1043
1044 switch (*mode) {
1045 case VADNormal:
1046 *vad = true;
1047 *dtx = true;
1048 *mode = VADAggr;
1049 break;
1050 case VADLowBitrate:
1051 *vad = true;
1052 *dtx = true;
1053 *mode = VADVeryAggr;
1054 break;
1055 case VADAggr:
1056 *vad = true;
1057 *dtx = true;
1058 *mode = VADLowBitrate;
1059 break;
1060 case VADVeryAggr:
1061 *vad = false;
1062 *dtx = false;
1063 *mode = VADNormal;
1064 break;
1065 default:
1066 *mode = VADNormal;
1067 }
1068
1069 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
1070
1071 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1072 myChannel->ResetStats();
1073
1074 CheckVADStatus(side);
1075 if (!_randomTest) {
1076 fprintf(stdout, "\n");
1077 fprintf(stdout, "-----------------------------------------------\n");
1078 }
1079
1080 // Fault Test
1081 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
1082 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +00001083
1084}
1085
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001086void APITest::CurrentCodec(char side) {
1087 CodecInst myCodec;
1088 if (side == 'A') {
1089 _acmA->SendCodec(&myCodec);
1090 } else {
1091 _acmB->SendCodec(&myCodec);
1092 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001093
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001094 if (!_randomTest) {
1095 fprintf(stdout, "\n\n");
1096 fprintf(stdout, "Send codec in Side A\n");
1097 fprintf(stdout, "----------------------------\n");
1098 fprintf(stdout, "Name................. %s\n", myCodec.plname);
1099 fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
1100 fprintf(stdout, "Rate................. %d\n", myCodec.rate);
1101 fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
1102 fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
1103 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001104
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001105 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001106}
1107
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001108void APITest::ChangeCodec(char side) {
1109 CodecInst myCodec;
1110 AudioCodingModule* myACM;
1111 uint8_t* codecCntr;
1112 bool* thereIsEncoder;
1113 bool* vad;
1114 bool* dtx;
1115 ACMVADMode* mode;
1116 Channel* myChannel;
1117 // Reset and Wait
1118 if (!_randomTest) {
1119 fprintf(stdout, "Reset Encoder Side A \n");
1120 }
1121 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001122 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001123 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001124 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001125 WriteLockScoped wl(_apiTestRWLock);
1126 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001127 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001128 vad = &_sendVADA;
1129 dtx = &_sendDTXA;
1130 mode = &_sendVADModeA;
1131 myChannel = _channel_A2B;
1132 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001133 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001134 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001135 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001136 WriteLockScoped wl(_apiTestRWLock);
1137 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001138 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001139 vad = &_sendVADB;
1140 dtx = &_sendDTXB;
1141 mode = &_sendVADModeB;
1142 myChannel = _channel_B2A;
1143 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001144
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001145 myACM->ResetEncoder();
1146 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001147
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001148 // Register the next codec
1149 do {
1150 *codecCntr =
1151 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1152 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001153
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001154 if (*codecCntr == 0) {
1155 //printf("Initialize Sender Side A \n");
1156 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001157 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001158 *thereIsEncoder = false;
1159 }
1160 CHECK_ERROR_MT(myACM->InitializeSender());
1161 Wait(1000);
1162
1163 // After Initialization CN is lost, re-register them
1164 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1165 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1166 }
1167 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1168 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1169 }
1170 // VAD & DTX are disabled after initialization
1171 *vad = false;
1172 *dtx = false;
1173 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001174 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001175
1176 AudioCodingModule::Codec(*codecCntr, &myCodec);
1177 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1178 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1179 || !STR_CASE_CMP(myCodec.plname, "RED"));
1180
1181 if (!_randomTest) {
1182 fprintf(stdout,"\n=====================================================\n");
1183 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1184 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1185 }
1186 //std::cout<< std::flush;
1187
1188 // NO DTX for supe-wideband codec at this point
1189 if (myCodec.plfreq == 32000) {
1190 *dtx = false;
1191 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1192
1193 }
1194
1195 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1196 myChannel->ResetStats();
1197 {
1198 WriteLockScoped wl(_apiTestRWLock);
1199 *thereIsEncoder = true;
1200 }
1201 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001202}
1203
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001204} // namespace webrtc