blob: 6893587d56df984f129f995292088cc469c334da [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);
414 if (_acmA->Process() < 0) {
415 // do not print error message if there is no encoder
416 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000417 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000418 ReadLockScoped rl(_apiTestRWLock);
419 thereIsEncoder = _thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000420 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000421
422 if (thereIsEncoder) {
423 fprintf(stderr, "\n>>>>> Process Failed at A <<<<<\n");
424 }
425 }
426 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000427}
428
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000429bool APITest::ProcessRunB() {
430 _processEventB->Wait(100);
431 if (_acmB->Process() < 0) {
432 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000433 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000434 ReadLockScoped rl(_apiTestRWLock);
435 thereIsEncoder = _thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000436 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000437 if (thereIsEncoder) {
438 fprintf(stderr, "\n>>>>> Process Failed at B <<<<<\n");
439 }
440 }
441 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000442}
443
444/*/
445 *
446 * In side A we test the APIs which are related to sender Side.
447 *
448/*/
449
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000450void APITest::RunTest(char thread) {
451 int testNum;
452 {
453 WriteLockScoped cs(_apiTestRWLock);
454 if (thread == 'A') {
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +0000455 _testNumA = (_testNumB + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000456 testNum = _testNumA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000457
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000458 _movingDot[_dotPositionA] = ' ';
459 if (_dotPositionA == 0) {
460 _dotMoveDirectionA = 1;
461 }
462 if (_dotPositionA == 19) {
463 _dotMoveDirectionA = -1;
464 }
465 _dotPositionA += _dotMoveDirectionA;
466 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
467 } else {
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +0000468 _testNumB = (_testNumA + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000469 testNum = _testNumB;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000470
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000471 _movingDot[_dotPositionB] = ' ';
472 if (_dotPositionB == 20) {
473 _dotMoveDirectionB = 1;
474 }
475 if (_dotPositionB == 39) {
476 _dotMoveDirectionB = -1;
477 }
478 _dotPositionB += _dotMoveDirectionB;
479 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
niklase@google.com470e71d2011-07-07 08:21:25 +0000480 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000481 //fprintf(stderr, "%c: %d \n", thread, testNum);
482 //fflush(stderr);
483 }
484 switch (testNum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000485 case 0:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000486 CurrentCodec('A');
487 ChangeCodec('A');
488 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000489 case 1:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000490 TestPlayout('B');
491 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000492 case 2:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000493 if (!_randomTest) {
494 fprintf(stdout, "\nTesting Delay ...\n");
495 }
496 TestDelay('A');
497 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000498 case 3:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000499 TestSendVAD('A');
500 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000501 case 4:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000502 TestRegisteration('A');
503 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000504 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000505 fprintf(stderr, "Wrong Test Number\n");
marpan@webrtc.org4765ca52014-11-03 20:10:26 +0000506 getc(stdin);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000507 exit(1);
508 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000509}
510
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000511bool APITest::APIRunA() {
512 _apiEventA->Wait(50);
niklase@google.com470e71d2011-07-07 08:21:25 +0000513
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000514 bool randomTest;
515 {
516 ReadLockScoped rl(_apiTestRWLock);
517 randomTest = _randomTest;
518 }
519 if (randomTest) {
520 RunTest('A');
521 } else {
522 CurrentCodec('A');
523 ChangeCodec('A');
524 TestPlayout('B');
525 if (_codecCntrA == 0) {
526 fprintf(stdout, "\nTesting Delay ...\n");
527 TestDelay('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000528 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000529 // VAD TEST
530 TestSendVAD('A');
531 TestRegisteration('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000532 }
533 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000534}
535
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000536bool APITest::APIRunB() {
537 _apiEventB->Wait(50);
538 bool randomTest;
539 {
540 ReadLockScoped rl(_apiTestRWLock);
541 randomTest = _randomTest;
542 }
543 //_apiEventB->Wait(2000);
544 if (randomTest) {
545 RunTest('B');
546 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000547
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000548 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000549}
550
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000551void APITest::Perform() {
552 SetUp();
niklase@google.com470e71d2011-07-07 08:21:25 +0000553
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000554 //--- THREADS
555 // A
556 // PUSH
557 ThreadWrapper* myPushAudioThreadA = ThreadWrapper::CreateThread(
558 PushAudioThreadA, this, kNormalPriority, "PushAudioThreadA");
559 CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
560 // PULL
561 ThreadWrapper* myPullAudioThreadA = ThreadWrapper::CreateThread(
562 PullAudioThreadA, this, kNormalPriority, "PullAudioThreadA");
563 CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
564 // Process
565 ThreadWrapper* myProcessThreadA = ThreadWrapper::CreateThread(
566 ProcessThreadA, this, kNormalPriority, "ProcessThreadA");
567 CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
568 // API
569 ThreadWrapper* myAPIThreadA = ThreadWrapper::CreateThread(APIThreadA, this,
570 kNormalPriority,
571 "APIThreadA");
572 CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
573 // B
574 // PUSH
575 ThreadWrapper* myPushAudioThreadB = ThreadWrapper::CreateThread(
576 PushAudioThreadB, this, kNormalPriority, "PushAudioThreadB");
577 CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
578 // PULL
579 ThreadWrapper* myPullAudioThreadB = ThreadWrapper::CreateThread(
580 PullAudioThreadB, this, kNormalPriority, "PullAudioThreadB");
581 CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
582 // Process
583 ThreadWrapper* myProcessThreadB = ThreadWrapper::CreateThread(
584 ProcessThreadB, this, kNormalPriority, "ProcessThreadB");
585 CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
586 // API
587 ThreadWrapper* myAPIThreadB = ThreadWrapper::CreateThread(APIThreadB, this,
588 kNormalPriority,
589 "APIThreadB");
590 CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000591
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000592 //_apiEventA->StartTimer(true, 5000);
593 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000594
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000595 _processEventA->StartTimer(true, 10);
596 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000597
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000598 _pullEventA->StartTimer(true, 10);
599 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000600
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000601 _pushEventA->StartTimer(true, 10);
602 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000603
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000604 // Keep main thread waiting for sender/receiver
605 // threads to complete
606 EventWrapper* completeEvent = EventWrapper::Create();
607 uint64_t startTime = TickTime::MillisecondTimestamp();
608 uint64_t currentTime;
609 // Run test in 2 minutes (120000 ms).
610 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000611 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000612 //ReadLockScoped rl(_apiTestRWLock);
613 //fprintf(stderr, "\r%s", _movingDot);
614 }
615 //fflush(stderr);
616 completeEvent->Wait(50);
617 currentTime = TickTime::MillisecondTimestamp();
618 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000619
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000620 //completeEvent->Wait(0xFFFFFFFF);
621 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
622 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000623
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000624 myPushAudioThreadA->Stop();
625 myPullAudioThreadA->Stop();
626 myProcessThreadA->Stop();
627 myAPIThreadA->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000628
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000629 delete myPushAudioThreadA;
630 delete myPullAudioThreadA;
631 delete myProcessThreadA;
632 delete myAPIThreadA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000633
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000634 myPushAudioThreadB->Stop();
635 myPullAudioThreadB->Stop();
636 myProcessThreadB->Stop();
637 myAPIThreadB->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000638
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000639 delete myPushAudioThreadB;
640 delete myPullAudioThreadB;
641 delete myProcessThreadB;
642 delete myAPIThreadB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000643}
644
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000645void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000646
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000647 bool dtxEnabled;
648 bool vadEnabled;
649 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000650
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000651 if (side == 'A') {
652 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
653 _acmA->RegisterVADCallback(NULL);
654 _vadCallbackA->Reset();
655 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000656
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000657 if (!_randomTest) {
658 if (_verbose) {
659 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
660 vadEnabled ? "ON" : "OFF", (int) vadMode);
661 Wait(5000);
662 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
663 } else {
664 Wait(5000);
665 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
666 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
667 (int) vadMode, _channel_A2B->BitRate());
668 }
669 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000670 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000671
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000672 if (dtxEnabled != _sendDTXA) {
673 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000674 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000675 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
676 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
677 }
678 if ((vadMode != _sendVADModeA) && vadEnabled) {
679 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
680 }
681 } else {
682 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
683
684 _acmB->RegisterVADCallback(NULL);
685 _vadCallbackB->Reset();
686 _acmB->RegisterVADCallback(_vadCallbackB);
687
688 if (!_randomTest) {
689 if (_verbose) {
690 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
691 vadEnabled ? "ON" : "OFF", (int) vadMode);
692 Wait(5000);
693 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
694 } else {
695 Wait(5000);
696 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
697 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
698 (int) vadMode, _channel_B2A->BitRate());
699 }
700 _vadCallbackB->PrintFrameTypes();
701 }
702
703 if (dtxEnabled != _sendDTXB) {
704 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
705 }
706 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
707 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
708 }
709 if ((vadMode != _sendVADModeB) && vadEnabled) {
710 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
711 }
712 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000713}
714
715// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000716void APITest::TestDelay(char side) {
717 AudioCodingModule* myACM;
718 Channel* myChannel;
719 int32_t* myMinDelay;
720 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000721
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000722 uint32_t inTimestamp = 0;
723 uint32_t outTimestamp = 0;
724 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000725
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000726 double averageEstimDelay = 0;
727 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000728
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000729 CircularBuffer estimDelayCB(100);
730 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000731
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000732 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000733 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000734 myChannel = _channel_B2A;
735 myMinDelay = &_minDelayA;
736 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000737 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000738 myChannel = _channel_A2B;
739 myMinDelay = &_minDelayB;
740 }
741
742 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
743
744 inTimestamp = myChannel->LastInTimestamp();
745 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
746
747 if (!_randomTest) {
748 myEvent->StartTimer(true, 30);
749 int n = 0;
750 int settlePoint = 5000;
751 while (n < settlePoint + 400) {
752 myEvent->Wait(1000);
753
754 inTimestamp = myChannel->LastInTimestamp();
755 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
756
757 //std::cout << outTimestamp << std::endl << std::flush;
758 estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
759 / ((double) myACM->ReceiveFrequency() / 1000.0);
760
761 estimDelayCB.Update(estimDelay);
762
763 estimDelayCB.ArithMean(averageEstimDelay);
764 //printf("\n %6.1f \n", estimDelay);
765 //std::cout << " " << std::flush;
766
767 if (_verbose) {
768 fprintf(stdout,
769 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
770 *myMinDelay, averageDelay, averageEstimDelay);
771 std::cout << " " << std::flush;
772 }
773 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
774 settlePoint = n;
775 }
776 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000777 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000778 myEvent->StopTimer();
779 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000780
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000781 if ((!_verbose) && (!_randomTest)) {
782 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000783 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000784 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000785
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000786 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000787
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000788 NetworkStatistics networkStat;
789 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000790
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000791 if (!_randomTest) {
792 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
793 fprintf(stdout, "--------------------------------------\n");
794 fprintf(stdout, "buffer-size............. %d\n",
795 networkStat.currentBufferSize);
796 fprintf(stdout, "Preferred buffer-size... %d\n",
797 networkStat.preferredBufferSize);
798 fprintf(stdout, "Peaky jitter mode........%d\n",
799 networkStat.jitterPeaksFound);
800 fprintf(stdout, "packet-size rate........ %d\n",
801 networkStat.currentPacketLossRate);
802 fprintf(stdout, "discard rate............ %d\n",
803 networkStat.currentDiscardRate);
804 fprintf(stdout, "expand rate............. %d\n",
805 networkStat.currentExpandRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000806 fprintf(stdout, "speech expand rate...... %d\n",
807 networkStat.currentSpeechExpandRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000808 fprintf(stdout, "Preemptive rate......... %d\n",
809 networkStat.currentPreemptiveRate);
810 fprintf(stdout, "Accelerate rate......... %d\n",
811 networkStat.currentAccelerateRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000812 fprintf(stdout, "Secondary decoded rate.. %d\n",
813 networkStat.currentSecondaryDecodedRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000814 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
815 fprintf(stdout, "Mean waiting time....... %d\n",
816 networkStat.meanWaitingTimeMs);
817 fprintf(stdout, "Median waiting time..... %d\n",
818 networkStat.medianWaitingTimeMs);
819 fprintf(stdout, "Min waiting time........ %d\n",
820 networkStat.minWaitingTimeMs);
821 fprintf(stdout, "Max waiting time........ %d\n",
822 networkStat.maxWaitingTimeMs);
823 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000824
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000825 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000826
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000827 if (!_randomTest) {
828 myEvent->Wait(500);
829 fprintf(stdout, "\n");
830 fprintf(stdout, "\n");
831 }
832 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000833}
834
835// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000836void APITest::TestRegisteration(char sendSide) {
837 AudioCodingModule* sendACM;
838 AudioCodingModule* receiveACM;
839 bool* thereIsDecoder;
840 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000841
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000842 if (!_randomTest) {
843 fprintf(stdout, "\n\n");
844 fprintf(stdout,
845 "---------------------------------------------------------\n");
846 fprintf(stdout, " Unregister/register Receive Codec\n");
847 fprintf(stdout,
848 "---------------------------------------------------------\n");
849 }
850
851 switch (sendSide) {
852 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000853 sendACM = _acmA.get();
854 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000855 thereIsDecoder = &_thereIsDecoderB;
856 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000857 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000858 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000859 sendACM = _acmB.get();
860 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000861 thereIsDecoder = &_thereIsDecoderA;
862 break;
863 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000864 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000865 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
866 sendSide);
867 exit(-1);
868 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000869
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000870 CodecInst myCodec;
871 if (sendACM->SendCodec(&myCodec) < 0) {
872 AudioCodingModule::Codec(_codecCntrA, &myCodec);
873 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000874
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000875 if (!_randomTest) {
876 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
877 fflush (stdout);
878 }
879 {
880 WriteLockScoped wl(_apiTestRWLock);
881 *thereIsDecoder = false;
882 }
883 //myEvent->Wait(20);
884 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
885 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000886
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000887 int currentPayload = myCodec.pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000888
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000889 if (!FixedPayloadTypeCodec(myCodec.plname)) {
890 int32_t i;
891 for (i = 0; i < 32; i++) {
892 if (!_payloadUsed[i]) {
893 if (!_randomTest) {
894 fprintf(stdout,
895 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000896 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000897 //myCodec.pltype = i + 96;
898 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
899 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
900 //myEvent->Wait(20);
901 //{
902 // WriteLockScoped wl(_apiTestRWLock);
903 // *thereIsDecoder = true;
904 //}
905 Wait(1000);
906
907 if (!_randomTest) {
908 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000909 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000910 //{
911 // WriteLockScoped wl(_apiTestRWLock);
912 // *thereIsDecoder = false;
913 //}
914 //myEvent->Wait(20);
915 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
916 Wait(1000);
917
918 myCodec.pltype = currentPayload;
919 if (!_randomTest) {
920 fprintf(stdout,
921 "Register receive codec with default Payload, AUDIO BACK.\n");
922 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000923 }
924 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000925 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000926 myEvent->Wait(20);
927 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000928 WriteLockScoped wl(_apiTestRWLock);
929 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000930 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000931 Wait(1000);
932
933 break;
934 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000935 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000936 if (i == 32) {
937 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
938 {
939 WriteLockScoped wl(_apiTestRWLock);
940 *thereIsDecoder = true;
941 }
942 }
943 } else {
944 if (!_randomTest) {
945 fprintf(stdout,
946 "Register receive codec with fixed Payload, AUDIO BACK.\n");
947 fflush (stdout);
948 }
949 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
950 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
951 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
952 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000953 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000954 WriteLockScoped wl(_apiTestRWLock);
955 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000956 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000957 }
958 delete myEvent;
959 if (!_randomTest) {
960 fprintf(stdout,
961 "---------------------------------------------------------\n");
962 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000963}
964
965// Playout Mode, background noise mode.
966// Receiver Frequency, playout frequency.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000967void APITest::TestPlayout(char receiveSide) {
968 AudioCodingModule* receiveACM;
969 AudioPlayoutMode* playoutMode = NULL;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000970 switch (receiveSide) {
971 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000972 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000973 playoutMode = &_playoutModeA;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000974 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000975 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000976 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000977 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000978 playoutMode = &_playoutModeB;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000979 break;
980 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000981 default:
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000982 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000983 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000984
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000985 int32_t receiveFreqHz = receiveACM->ReceiveFrequency();
986 int32_t playoutFreqHz = receiveACM->PlayoutFrequency();
987
988 CHECK_ERROR_MT(receiveFreqHz);
989 CHECK_ERROR_MT(playoutFreqHz);
990
niklase@google.com470e71d2011-07-07 08:21:25 +0000991
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000992 char playoutString[25];
993 switch (*playoutMode) {
994 case voice: {
995 *playoutMode = fax;
996 strncpy(playoutString, "FAX", 25);
997 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000998 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000999 case fax: {
1000 *playoutMode = streaming;
1001 strncpy(playoutString, "Streaming", 25);
1002 break;
1003 }
1004 case streaming: {
1005 *playoutMode = voice;
1006 strncpy(playoutString, "Voice", 25);
1007 break;
1008 }
1009 default:
1010 *playoutMode = voice;
1011 strncpy(playoutString, "Voice", 25);
1012 }
1013 CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
1014 playoutString[24] = '\0';
1015
1016 if (!_randomTest) {
1017 fprintf(stdout, "\n");
1018 fprintf(stdout, "In Side %c\n", receiveSide);
1019 fprintf(stdout, "---------------------------------\n");
1020 fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
1021 fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
1022 fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001023 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001024}
1025
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001026void APITest::TestSendVAD(char side) {
1027 if (_randomTest) {
1028 return;
1029 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001030
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001031 bool* vad;
1032 bool* dtx;
1033 ACMVADMode* mode;
1034 Channel* myChannel;
1035 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +00001036
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001037 CodecInst myCodec;
1038 if (!_randomTest) {
1039 fprintf(stdout, "\n\n");
1040 fprintf(stdout, "-----------------------------------------------\n");
1041 fprintf(stdout, " Test VAD API\n");
1042 fprintf(stdout, "-----------------------------------------------\n");
1043 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001044
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001045 if (side == 'A') {
1046 AudioCodingModule::Codec(_codecCntrA, &myCodec);
1047 vad = &_sendVADA;
1048 dtx = &_sendDTXA;
1049 mode = &_sendVADModeA;
1050 myChannel = _channel_A2B;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001051 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001052 } else {
1053 AudioCodingModule::Codec(_codecCntrB, &myCodec);
1054 vad = &_sendVADB;
1055 dtx = &_sendDTXB;
1056 mode = &_sendVADModeB;
1057 myChannel = _channel_B2A;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001058 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001059 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001060
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001061 CheckVADStatus(side);
1062 if (!_randomTest) {
1063 fprintf(stdout, "\n\n");
1064 }
1065
1066 switch (*mode) {
1067 case VADNormal:
1068 *vad = true;
1069 *dtx = true;
1070 *mode = VADAggr;
1071 break;
1072 case VADLowBitrate:
1073 *vad = true;
1074 *dtx = true;
1075 *mode = VADVeryAggr;
1076 break;
1077 case VADAggr:
1078 *vad = true;
1079 *dtx = true;
1080 *mode = VADLowBitrate;
1081 break;
1082 case VADVeryAggr:
1083 *vad = false;
1084 *dtx = false;
1085 *mode = VADNormal;
1086 break;
1087 default:
1088 *mode = VADNormal;
1089 }
1090
1091 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
1092
1093 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1094 myChannel->ResetStats();
1095
1096 CheckVADStatus(side);
1097 if (!_randomTest) {
1098 fprintf(stdout, "\n");
1099 fprintf(stdout, "-----------------------------------------------\n");
1100 }
1101
1102 // Fault Test
1103 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
1104 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +00001105
1106}
1107
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001108void APITest::CurrentCodec(char side) {
1109 CodecInst myCodec;
1110 if (side == 'A') {
1111 _acmA->SendCodec(&myCodec);
1112 } else {
1113 _acmB->SendCodec(&myCodec);
1114 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001115
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001116 if (!_randomTest) {
1117 fprintf(stdout, "\n\n");
1118 fprintf(stdout, "Send codec in Side A\n");
1119 fprintf(stdout, "----------------------------\n");
1120 fprintf(stdout, "Name................. %s\n", myCodec.plname);
1121 fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
1122 fprintf(stdout, "Rate................. %d\n", myCodec.rate);
1123 fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
1124 fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
1125 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001126
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001127 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001128}
1129
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001130void APITest::ChangeCodec(char side) {
1131 CodecInst myCodec;
1132 AudioCodingModule* myACM;
1133 uint8_t* codecCntr;
1134 bool* thereIsEncoder;
1135 bool* vad;
1136 bool* dtx;
1137 ACMVADMode* mode;
1138 Channel* myChannel;
1139 // Reset and Wait
1140 if (!_randomTest) {
1141 fprintf(stdout, "Reset Encoder Side A \n");
1142 }
1143 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001144 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001145 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001146 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001147 WriteLockScoped wl(_apiTestRWLock);
1148 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001149 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001150 vad = &_sendVADA;
1151 dtx = &_sendDTXA;
1152 mode = &_sendVADModeA;
1153 myChannel = _channel_A2B;
1154 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001155 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001156 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001157 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001158 WriteLockScoped wl(_apiTestRWLock);
1159 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001160 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001161 vad = &_sendVADB;
1162 dtx = &_sendDTXB;
1163 mode = &_sendVADModeB;
1164 myChannel = _channel_B2A;
1165 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001166
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001167 myACM->ResetEncoder();
1168 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001169
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001170 // Register the next codec
1171 do {
1172 *codecCntr =
1173 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1174 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001175
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001176 if (*codecCntr == 0) {
1177 //printf("Initialize Sender Side A \n");
1178 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001179 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001180 *thereIsEncoder = false;
1181 }
1182 CHECK_ERROR_MT(myACM->InitializeSender());
1183 Wait(1000);
1184
1185 // After Initialization CN is lost, re-register them
1186 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1187 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1188 }
1189 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1190 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1191 }
1192 // VAD & DTX are disabled after initialization
1193 *vad = false;
1194 *dtx = false;
1195 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001196 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001197
1198 AudioCodingModule::Codec(*codecCntr, &myCodec);
1199 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1200 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1201 || !STR_CASE_CMP(myCodec.plname, "RED"));
1202
1203 if (!_randomTest) {
1204 fprintf(stdout,"\n=====================================================\n");
1205 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1206 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1207 }
1208 //std::cout<< std::flush;
1209
1210 // NO DTX for supe-wideband codec at this point
1211 if (myCodec.plfreq == 32000) {
1212 *dtx = false;
1213 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1214
1215 }
1216
1217 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1218 myChannel->ResetStats();
1219 {
1220 WriteLockScoped wl(_apiTestRWLock);
1221 *thereIsEncoder = true;
1222 }
1223 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001224}
1225
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001226} // namespace webrtc