blob: 83b24a87d524184a9efe816183313eb6aa25264b [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
andrew@webrtc.org63a50982012-05-02 23:56:37 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000011#include "webrtc/modules/audio_coding/main/test/APITest.h"
12
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <ctype.h>
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000014#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000017
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +000018#include <iostream>
19#include <ostream>
20#include <string>
21
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000022#include "testing/gtest/include/gtest/gtest.h"
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000023#include "webrtc/common.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000024#include "webrtc/common_types.h"
25#include "webrtc/engine_configurations.h"
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +000026#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000027#include "webrtc/modules/audio_coding/main/test/utility.h"
28#include "webrtc/system_wrappers/interface/event_wrapper.h"
29#include "webrtc/system_wrappers/interface/thread_wrapper.h"
30#include "webrtc/system_wrappers/interface/tick_util.h"
31#include "webrtc/system_wrappers/interface/trace.h"
32#include "webrtc/test/testsupport/fileutils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000033
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000034namespace webrtc {
35
niklase@google.com470e71d2011-07-07 08:21:25 +000036#define TEST_DURATION_SEC 600
niklase@google.com470e71d2011-07-07 08:21:25 +000037#define NUMBER_OF_SENDER_TESTS 6
niklase@google.com470e71d2011-07-07 08:21:25 +000038#define MAX_FILE_NAME_LENGTH_BYTE 500
kjellander@webrtc.org5490c712011-12-21 13:34:18 +000039#define CHECK_THREAD_NULLITY(myThread, S) \
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000040 if(myThread != NULL) { \
pbos@webrtc.org86639732015-03-13 00:06:21 +000041 (myThread)->Start(); \
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000042 } else { \
43 ADD_FAILURE() << S; \
44 }
niklase@google.com470e71d2011-07-07 08:21:25 +000045
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000046void APITest::Wait(uint32_t waitLengthMs) {
47 if (_randomTest) {
48 return;
49 } else {
50 EventWrapper* myEvent = EventWrapper::Create();
51 myEvent->Wait(waitLengthMs);
52 delete myEvent;
53 return;
54 }
niklase@google.com470e71d2011-07-07 08:21:25 +000055}
56
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000057APITest::APITest(const Config& config)
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +000058 : _acmA(AudioCodingModule::Create(1)),
59 _acmB(AudioCodingModule::Create(2)),
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000060 _channel_A2B(NULL),
61 _channel_B2A(NULL),
62 _writeToFile(true),
63 _pullEventA(NULL),
64 _pushEventA(NULL),
65 _processEventA(NULL),
66 _apiEventA(NULL),
67 _pullEventB(NULL),
68 _pushEventB(NULL),
69 _processEventB(NULL),
70 _apiEventB(NULL),
71 _codecCntrA(0),
72 _codecCntrB(0),
73 _thereIsEncoderA(false),
74 _thereIsEncoderB(false),
75 _thereIsDecoderA(false),
76 _thereIsDecoderB(false),
77 _sendVADA(false),
78 _sendDTXA(false),
79 _sendVADModeA(VADNormal),
80 _sendVADB(false),
81 _sendDTXB(false),
82 _sendVADModeB(VADNormal),
83 _minDelayA(0),
84 _minDelayB(0),
85 _dotPositionA(0),
86 _dotMoveDirectionA(1),
87 _dotPositionB(39),
88 _dotMoveDirectionB(-1),
89 _dtmfCallback(NULL),
90 _vadCallbackA(NULL),
91 _vadCallbackB(NULL),
92 _apiTestRWLock(*RWLockWrapper::CreateRWLock()),
93 _randomTest(false),
94 _testNumA(0),
95 _testNumB(1) {
96 int n;
97 for (n = 0; n < 32; n++) {
98 _payloadUsed[n] = false;
99 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000100
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000101 _movingDot[40] = '\0';
niklase@google.com470e71d2011-07-07 08:21:25 +0000102
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000103 for (int n = 0; n < 40; n++) {
104 _movingDot[n] = ' ';
105 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000106}
107
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000108APITest::~APITest() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000109 DELETE_POINTER(_channel_A2B);
110 DELETE_POINTER(_channel_B2A);
niklase@google.com470e71d2011-07-07 08:21:25 +0000111
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000112 DELETE_POINTER(_pushEventA);
113 DELETE_POINTER(_pullEventA);
114 DELETE_POINTER(_processEventA);
115 DELETE_POINTER(_apiEventA);
niklase@google.com470e71d2011-07-07 08:21:25 +0000116
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000117 DELETE_POINTER(_pushEventB);
118 DELETE_POINTER(_pullEventB);
119 DELETE_POINTER(_processEventB);
120 DELETE_POINTER(_apiEventB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000121
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000122 _inFileA.Close();
123 _outFileA.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000124
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000125 _inFileB.Close();
126 _outFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000127
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000128 DELETE_POINTER(_dtmfCallback);
129 DELETE_POINTER(_vadCallbackA);
130 DELETE_POINTER(_vadCallbackB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000131
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000132 delete &_apiTestRWLock;
niklase@google.com470e71d2011-07-07 08:21:25 +0000133}
134
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000135int16_t APITest::SetUp() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000136 CodecInst dummyCodec;
137 int lastPayloadType = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000138
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000139 int16_t numCodecs = _acmA->NumberOfCodecs();
140 for (uint8_t n = 0; n < numCodecs; n++) {
141 AudioCodingModule::Codec(n, &dummyCodec);
142 if ((STR_CASE_CMP(dummyCodec.plname, "CN") == 0)
143 && (dummyCodec.plfreq == 32000)) {
144 continue;
niklase@google.com470e71d2011-07-07 08:21:25 +0000145 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000146
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000147 printf("Register Receive Codec %s ", dummyCodec.plname);
niklase@google.com470e71d2011-07-07 08:21:25 +0000148
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000149 if ((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
150 // Check registration with an already occupied payload type
151 int currentPayloadType = dummyCodec.pltype;
152 dummyCodec.pltype = 97; //lastPayloadType;
153 CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
154 dummyCodec.pltype = currentPayloadType;
155 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000156
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000157 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
158 // test if re-registration works;
159 CodecInst nextCodec;
160 int currentPayloadType = dummyCodec.pltype;
161 AudioCodingModule::Codec(n + 1, &nextCodec);
162 dummyCodec.pltype = nextCodec.pltype;
163 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
164 _acmB->RegisterReceiveCodec(dummyCodec);
165 }
166 dummyCodec.pltype = currentPayloadType;
167 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000168
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000169 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
170 // test if un-registration works;
171 CodecInst nextCodec;
172 AudioCodingModule::Codec(n + 1, &nextCodec);
173 nextCodec.pltype = dummyCodec.pltype;
174 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
175 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
176 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
177 }
178 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000179
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000180 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
181 printf(" side A done!");
182 CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
183 printf(" side B done!\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000184
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000185 if (!strcmp(dummyCodec.plname, "CN")) {
186 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
187 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
188 }
189 lastPayloadType = dummyCodec.pltype;
190 if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
191 _payloadUsed[lastPayloadType - 96] = true;
192 }
193 }
194 _thereIsDecoderA = true;
195 _thereIsDecoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000196
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000197 // Register Send Codec
198 AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
199 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
200 _thereIsEncoderA = true;
201 //
202 AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
203 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
204 _thereIsEncoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000205
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000206 uint16_t frequencyHz;
niklase@google.com470e71d2011-07-07 08:21:25 +0000207
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000208 printf("\n\nAPI Test\n");
209 printf("========\n");
210 printf("Hit enter to accept the default values indicated in []\n\n");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000211
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000212 //--- Input A
213 std::string file_name = webrtc::test::ResourcePath(
214 "audio_coding/testfile32kHz", "pcm");
215 frequencyHz = 32000;
216 printf("Enter input file at side A [%s]: ", file_name.c_str());
217 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
218 _inFileA.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000219
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000220 //--- Output A
221 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
222 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
223 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
224 _outFileA.Open(out_file_a, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000225
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000226 //--- Input B
227 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
228 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
229 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
230 _inFileB.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000231
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000232 //--- Output B
233 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
234 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
235 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
236 _outFileB.Open(out_file_b, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000237
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000238 //--- Set A-to-B channel
239 _channel_A2B = new Channel(2);
240 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000241 _channel_A2B->RegisterReceiverACM(_acmB.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000242
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000243 //--- Set B-to-A channel
244 _channel_B2A = new Channel(1);
245 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000246 _channel_B2A->RegisterReceiverACM(_acmA.get());
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +0000247
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000248 //--- EVENT TIMERS
249 // A
250 _pullEventA = EventWrapper::Create();
251 _pushEventA = EventWrapper::Create();
252 _processEventA = EventWrapper::Create();
253 _apiEventA = EventWrapper::Create();
254 // B
255 _pullEventB = EventWrapper::Create();
256 _pushEventB = EventWrapper::Create();
257 _processEventB = EventWrapper::Create();
258 _apiEventB = EventWrapper::Create();
259
260 //--- I/O params
261 // A
262 _outFreqHzA = _outFileA.SamplingFrequency();
263 // B
264 _outFreqHzB = _outFileB.SamplingFrequency();
265
266 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
267
268 char print[11];
269
270 // Create a trace file.
271 Trace::CreateTrace();
272 Trace::SetTraceFile(
273 (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
274
275 printf("\nRandom Test (y/n)?");
276 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
277 print[10] = '\0';
278 if (strstr(print, "y") != NULL) {
279 _randomTest = true;
280 _verbose = false;
281 _writeToFile = false;
282 } else {
283 _randomTest = false;
284 printf("\nPrint Tests (y/n)? ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000285 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000286 print[10] = '\0';
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000287 if (strstr(print, "y") == NULL) {
288 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
289 _verbose = false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000290 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000291 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000292
293#ifdef WEBRTC_DTMF_DETECTION
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000294 _dtmfCallback = new DTMFDetector;
niklase@google.com470e71d2011-07-07 08:21:25 +0000295#endif
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000296 _vadCallbackA = new VADCallback;
297 _vadCallbackB = new VADCallback;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000298
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000299 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000300}
301
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000302bool APITest::PushAudioThreadA(void* obj) {
303 return static_cast<APITest*>(obj)->PushAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000304}
305
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000306bool APITest::PushAudioThreadB(void* obj) {
307 return static_cast<APITest*>(obj)->PushAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000308}
309
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000310bool APITest::PullAudioThreadA(void* obj) {
311 return static_cast<APITest*>(obj)->PullAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000312}
313
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000314bool APITest::PullAudioThreadB(void* obj) {
315 return static_cast<APITest*>(obj)->PullAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000316}
317
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000318bool APITest::ProcessThreadA(void* obj) {
319 return static_cast<APITest*>(obj)->ProcessRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000320}
321
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000322bool APITest::ProcessThreadB(void* obj) {
323 return static_cast<APITest*>(obj)->ProcessRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000324}
325
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000326bool APITest::APIThreadA(void* obj) {
327 return static_cast<APITest*>(obj)->APIRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000328}
329
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000330bool APITest::APIThreadB(void* obj) {
331 return static_cast<APITest*>(obj)->APIRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000332}
333
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000334bool APITest::PullAudioRunA() {
335 _pullEventA->Wait(100);
336 AudioFrame audioFrame;
337 if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame) < 0) {
338 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000340 ReadLockScoped rl(_apiTestRWLock);
341 thereIsDecoder = _thereIsDecoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000343 if (thereIsDecoder) {
344 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000345 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000346 } else {
347 if (_writeToFile) {
348 _outFileA.Write10MsData(audioFrame);
349 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000350 }
351 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000352}
353
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000354bool APITest::PullAudioRunB() {
355 _pullEventB->Wait(100);
356 AudioFrame audioFrame;
357 if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame) < 0) {
358 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000359 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000360 ReadLockScoped rl(_apiTestRWLock);
361 thereIsDecoder = _thereIsDecoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000362 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000363 if (thereIsDecoder) {
364 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
365 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000366 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000367 } else {
368 if (_writeToFile) {
369 _outFileB.Write10MsData(audioFrame);
370 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000371 }
372 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000373}
374
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000375bool APITest::PushAudioRunA() {
376 _pushEventA->Wait(100);
377 AudioFrame audioFrame;
378 _inFileA.Read10MsData(audioFrame);
379 if (_acmA->Add10MsData(audioFrame) < 0) {
380 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000381 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000382 ReadLockScoped rl(_apiTestRWLock);
383 thereIsEncoder = _thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000384 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000385 if (thereIsEncoder) {
386 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
387 }
388 }
389 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000390}
391
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000392bool APITest::PushAudioRunB() {
393 _pushEventB->Wait(100);
394 AudioFrame audioFrame;
395 _inFileB.Read10MsData(audioFrame);
396 if (_acmB->Add10MsData(audioFrame) < 0) {
397 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000398 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000399 ReadLockScoped rl(_apiTestRWLock);
400 thereIsEncoder = _thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000401 }
402
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000403 if (thereIsEncoder) {
404 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
405 }
406 }
407
408 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000409}
410
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000411bool APITest::ProcessRunA() {
412 _processEventA->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000413 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000414}
415
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000416bool APITest::ProcessRunB() {
417 _processEventB->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000418 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000419}
420
421/*/
422 *
423 * In side A we test the APIs which are related to sender Side.
424 *
425/*/
426
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000427void APITest::RunTest(char thread) {
428 int testNum;
429 {
430 WriteLockScoped cs(_apiTestRWLock);
431 if (thread == 'A') {
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +0000432 _testNumA = (_testNumB + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000433 testNum = _testNumA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000434
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000435 _movingDot[_dotPositionA] = ' ';
436 if (_dotPositionA == 0) {
437 _dotMoveDirectionA = 1;
438 }
439 if (_dotPositionA == 19) {
440 _dotMoveDirectionA = -1;
441 }
442 _dotPositionA += _dotMoveDirectionA;
443 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
444 } else {
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +0000445 _testNumB = (_testNumA + 1 + (rand() % 4)) % 5;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000446 testNum = _testNumB;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000447
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000448 _movingDot[_dotPositionB] = ' ';
449 if (_dotPositionB == 20) {
450 _dotMoveDirectionB = 1;
451 }
452 if (_dotPositionB == 39) {
453 _dotMoveDirectionB = -1;
454 }
455 _dotPositionB += _dotMoveDirectionB;
456 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
niklase@google.com470e71d2011-07-07 08:21:25 +0000457 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000458 //fprintf(stderr, "%c: %d \n", thread, testNum);
459 //fflush(stderr);
460 }
461 switch (testNum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000462 case 0:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000463 CurrentCodec('A');
464 ChangeCodec('A');
465 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000466 case 1:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000467 TestPlayout('B');
468 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000469 case 2:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000470 if (!_randomTest) {
471 fprintf(stdout, "\nTesting Delay ...\n");
472 }
473 TestDelay('A');
474 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000475 case 3:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000476 TestSendVAD('A');
477 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000478 case 4:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000479 TestRegisteration('A');
480 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000481 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000482 fprintf(stderr, "Wrong Test Number\n");
marpan@webrtc.org4765ca52014-11-03 20:10:26 +0000483 getc(stdin);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000484 exit(1);
485 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000486}
487
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000488bool APITest::APIRunA() {
489 _apiEventA->Wait(50);
niklase@google.com470e71d2011-07-07 08:21:25 +0000490
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000491 bool randomTest;
492 {
493 ReadLockScoped rl(_apiTestRWLock);
494 randomTest = _randomTest;
495 }
496 if (randomTest) {
497 RunTest('A');
498 } else {
499 CurrentCodec('A');
500 ChangeCodec('A');
501 TestPlayout('B');
502 if (_codecCntrA == 0) {
503 fprintf(stdout, "\nTesting Delay ...\n");
504 TestDelay('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000505 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000506 // VAD TEST
507 TestSendVAD('A');
508 TestRegisteration('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000509 }
510 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000511}
512
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000513bool APITest::APIRunB() {
514 _apiEventB->Wait(50);
515 bool randomTest;
516 {
517 ReadLockScoped rl(_apiTestRWLock);
518 randomTest = _randomTest;
519 }
520 //_apiEventB->Wait(2000);
521 if (randomTest) {
522 RunTest('B');
523 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000524
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000525 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000526}
527
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000528void APITest::Perform() {
529 SetUp();
niklase@google.com470e71d2011-07-07 08:21:25 +0000530
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000531 //--- THREADS
532 // A
533 // PUSH
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000534 rtc::scoped_ptr<ThreadWrapper> myPushAudioThreadA =
tommi@webrtc.org90a1cb42015-03-22 14:33:54 +0000535 ThreadWrapper::CreateThread(PushAudioThreadA, this, kNormalPriority,
536 "PushAudioThreadA");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000537 CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
538 // PULL
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000539 rtc::scoped_ptr<ThreadWrapper> myPullAudioThreadA =
tommi@webrtc.org90a1cb42015-03-22 14:33:54 +0000540 ThreadWrapper::CreateThread(PullAudioThreadA, this, kNormalPriority,
541 "PullAudioThreadA");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000542 CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
543 // Process
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000544 rtc::scoped_ptr<ThreadWrapper> myProcessThreadA = ThreadWrapper::CreateThread(
tommi@webrtc.org90a1cb42015-03-22 14:33:54 +0000545 ProcessThreadA, this, kNormalPriority, "ProcessThreadA");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000546 CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
547 // API
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000548 rtc::scoped_ptr<ThreadWrapper> myAPIThreadA = ThreadWrapper::CreateThread(
tommi@webrtc.org90a1cb42015-03-22 14:33:54 +0000549 APIThreadA, this, kNormalPriority, "APIThreadA");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000550 CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
551 // B
552 // PUSH
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000553 rtc::scoped_ptr<ThreadWrapper> myPushAudioThreadB =
tommi@webrtc.org90a1cb42015-03-22 14:33:54 +0000554 ThreadWrapper::CreateThread(PushAudioThreadB, this, kNormalPriority,
555 "PushAudioThreadB");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000556 CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
557 // PULL
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000558 rtc::scoped_ptr<ThreadWrapper> myPullAudioThreadB =
tommi@webrtc.org90a1cb42015-03-22 14:33:54 +0000559 ThreadWrapper::CreateThread(PullAudioThreadB, this, kNormalPriority,
560 "PullAudioThreadB");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000561 CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
562 // Process
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000563 rtc::scoped_ptr<ThreadWrapper> myProcessThreadB = ThreadWrapper::CreateThread(
tommi@webrtc.org90a1cb42015-03-22 14:33:54 +0000564 ProcessThreadB, this, kNormalPriority, "ProcessThreadB");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000565 CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
566 // API
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000567 rtc::scoped_ptr<ThreadWrapper> myAPIThreadB = ThreadWrapper::CreateThread(
tommi@webrtc.org90a1cb42015-03-22 14:33:54 +0000568 APIThreadB, this, kNormalPriority, "APIThreadB");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000569 CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000570
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000571 //_apiEventA->StartTimer(true, 5000);
572 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000573
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000574 _processEventA->StartTimer(true, 10);
575 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000576
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000577 _pullEventA->StartTimer(true, 10);
578 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000579
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000580 _pushEventA->StartTimer(true, 10);
581 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000582
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000583 // Keep main thread waiting for sender/receiver
584 // threads to complete
585 EventWrapper* completeEvent = EventWrapper::Create();
586 uint64_t startTime = TickTime::MillisecondTimestamp();
587 uint64_t currentTime;
588 // Run test in 2 minutes (120000 ms).
589 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000590 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000591 //ReadLockScoped rl(_apiTestRWLock);
592 //fprintf(stderr, "\r%s", _movingDot);
593 }
594 //fflush(stderr);
595 completeEvent->Wait(50);
596 currentTime = TickTime::MillisecondTimestamp();
597 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000598
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000599 //completeEvent->Wait(0xFFFFFFFF);
600 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
601 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000602
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000603 myPushAudioThreadA->Stop();
604 myPullAudioThreadA->Stop();
605 myProcessThreadA->Stop();
606 myAPIThreadA->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000607
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000608 myPushAudioThreadB->Stop();
609 myPullAudioThreadB->Stop();
610 myProcessThreadB->Stop();
611 myAPIThreadB->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000612}
613
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000614void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000615
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000616 bool dtxEnabled;
617 bool vadEnabled;
618 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000619
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000620 if (side == 'A') {
621 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
622 _acmA->RegisterVADCallback(NULL);
623 _vadCallbackA->Reset();
624 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000625
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000626 if (!_randomTest) {
627 if (_verbose) {
628 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
629 vadEnabled ? "ON" : "OFF", (int) vadMode);
630 Wait(5000);
631 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
632 } else {
633 Wait(5000);
634 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
635 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
636 (int) vadMode, _channel_A2B->BitRate());
637 }
638 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000639 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000640
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000641 if (dtxEnabled != _sendDTXA) {
642 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000643 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000644 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
645 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
646 }
647 if ((vadMode != _sendVADModeA) && vadEnabled) {
648 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
649 }
650 } else {
651 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
652
653 _acmB->RegisterVADCallback(NULL);
654 _vadCallbackB->Reset();
655 _acmB->RegisterVADCallback(_vadCallbackB);
656
657 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_B2A->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_B2A->BitRate());
668 }
669 _vadCallbackB->PrintFrameTypes();
670 }
671
672 if (dtxEnabled != _sendDTXB) {
673 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
674 }
675 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
676 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
677 }
678 if ((vadMode != _sendVADModeB) && vadEnabled) {
679 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
680 }
681 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000682}
683
684// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000685void APITest::TestDelay(char side) {
686 AudioCodingModule* myACM;
687 Channel* myChannel;
688 int32_t* myMinDelay;
689 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000690
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000691 uint32_t inTimestamp = 0;
692 uint32_t outTimestamp = 0;
693 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000694
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000695 double averageEstimDelay = 0;
696 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000697
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000698 CircularBuffer estimDelayCB(100);
699 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000700
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000701 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000702 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000703 myChannel = _channel_B2A;
704 myMinDelay = &_minDelayA;
705 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000706 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000707 myChannel = _channel_A2B;
708 myMinDelay = &_minDelayB;
709 }
710
711 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
712
713 inTimestamp = myChannel->LastInTimestamp();
714 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
715
716 if (!_randomTest) {
717 myEvent->StartTimer(true, 30);
718 int n = 0;
719 int settlePoint = 5000;
720 while (n < settlePoint + 400) {
721 myEvent->Wait(1000);
722
723 inTimestamp = myChannel->LastInTimestamp();
724 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
725
726 //std::cout << outTimestamp << std::endl << std::flush;
727 estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
728 / ((double) myACM->ReceiveFrequency() / 1000.0);
729
730 estimDelayCB.Update(estimDelay);
731
732 estimDelayCB.ArithMean(averageEstimDelay);
733 //printf("\n %6.1f \n", estimDelay);
734 //std::cout << " " << std::flush;
735
736 if (_verbose) {
737 fprintf(stdout,
738 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
739 *myMinDelay, averageDelay, averageEstimDelay);
740 std::cout << " " << std::flush;
741 }
742 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
743 settlePoint = n;
744 }
745 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000746 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000747 myEvent->StopTimer();
748 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000749
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000750 if ((!_verbose) && (!_randomTest)) {
751 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000752 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000753 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000754
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000755 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000756
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000757 NetworkStatistics networkStat;
758 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000759
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000760 if (!_randomTest) {
761 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
762 fprintf(stdout, "--------------------------------------\n");
763 fprintf(stdout, "buffer-size............. %d\n",
764 networkStat.currentBufferSize);
765 fprintf(stdout, "Preferred buffer-size... %d\n",
766 networkStat.preferredBufferSize);
767 fprintf(stdout, "Peaky jitter mode........%d\n",
768 networkStat.jitterPeaksFound);
769 fprintf(stdout, "packet-size rate........ %d\n",
770 networkStat.currentPacketLossRate);
771 fprintf(stdout, "discard rate............ %d\n",
772 networkStat.currentDiscardRate);
773 fprintf(stdout, "expand rate............. %d\n",
774 networkStat.currentExpandRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000775 fprintf(stdout, "speech expand rate...... %d\n",
776 networkStat.currentSpeechExpandRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000777 fprintf(stdout, "Preemptive rate......... %d\n",
778 networkStat.currentPreemptiveRate);
779 fprintf(stdout, "Accelerate rate......... %d\n",
780 networkStat.currentAccelerateRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000781 fprintf(stdout, "Secondary decoded rate.. %d\n",
782 networkStat.currentSecondaryDecodedRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000783 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
784 fprintf(stdout, "Mean waiting time....... %d\n",
785 networkStat.meanWaitingTimeMs);
786 fprintf(stdout, "Median waiting time..... %d\n",
787 networkStat.medianWaitingTimeMs);
788 fprintf(stdout, "Min waiting time........ %d\n",
789 networkStat.minWaitingTimeMs);
790 fprintf(stdout, "Max waiting time........ %d\n",
791 networkStat.maxWaitingTimeMs);
792 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000793
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000794 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000795
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000796 if (!_randomTest) {
797 myEvent->Wait(500);
798 fprintf(stdout, "\n");
799 fprintf(stdout, "\n");
800 }
801 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000802}
803
804// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000805void APITest::TestRegisteration(char sendSide) {
806 AudioCodingModule* sendACM;
807 AudioCodingModule* receiveACM;
808 bool* thereIsDecoder;
809 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000810
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000811 if (!_randomTest) {
812 fprintf(stdout, "\n\n");
813 fprintf(stdout,
814 "---------------------------------------------------------\n");
815 fprintf(stdout, " Unregister/register Receive Codec\n");
816 fprintf(stdout,
817 "---------------------------------------------------------\n");
818 }
819
820 switch (sendSide) {
821 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000822 sendACM = _acmA.get();
823 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000824 thereIsDecoder = &_thereIsDecoderB;
825 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000826 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000827 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000828 sendACM = _acmB.get();
829 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000830 thereIsDecoder = &_thereIsDecoderA;
831 break;
832 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000833 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000834 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
835 sendSide);
836 exit(-1);
837 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000838
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000839 CodecInst myCodec;
840 if (sendACM->SendCodec(&myCodec) < 0) {
841 AudioCodingModule::Codec(_codecCntrA, &myCodec);
842 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000843
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000844 if (!_randomTest) {
845 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
846 fflush (stdout);
847 }
848 {
849 WriteLockScoped wl(_apiTestRWLock);
850 *thereIsDecoder = false;
851 }
852 //myEvent->Wait(20);
853 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
854 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000855
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000856 int currentPayload = myCodec.pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000857
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000858 if (!FixedPayloadTypeCodec(myCodec.plname)) {
859 int32_t i;
860 for (i = 0; i < 32; i++) {
861 if (!_payloadUsed[i]) {
862 if (!_randomTest) {
863 fprintf(stdout,
864 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000865 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000866 //myCodec.pltype = i + 96;
867 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
868 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
869 //myEvent->Wait(20);
870 //{
871 // WriteLockScoped wl(_apiTestRWLock);
872 // *thereIsDecoder = true;
873 //}
874 Wait(1000);
875
876 if (!_randomTest) {
877 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000878 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000879 //{
880 // WriteLockScoped wl(_apiTestRWLock);
881 // *thereIsDecoder = false;
882 //}
883 //myEvent->Wait(20);
884 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
885 Wait(1000);
886
887 myCodec.pltype = currentPayload;
888 if (!_randomTest) {
889 fprintf(stdout,
890 "Register receive codec with default Payload, AUDIO BACK.\n");
891 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000892 }
893 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000894 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000895 myEvent->Wait(20);
896 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000897 WriteLockScoped wl(_apiTestRWLock);
898 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000899 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000900 Wait(1000);
901
902 break;
903 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000904 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000905 if (i == 32) {
906 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
907 {
908 WriteLockScoped wl(_apiTestRWLock);
909 *thereIsDecoder = true;
910 }
911 }
912 } else {
913 if (!_randomTest) {
914 fprintf(stdout,
915 "Register receive codec with fixed Payload, AUDIO BACK.\n");
916 fflush (stdout);
917 }
918 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
919 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
920 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
921 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000922 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000923 WriteLockScoped wl(_apiTestRWLock);
924 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000925 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000926 }
927 delete myEvent;
928 if (!_randomTest) {
929 fprintf(stdout,
930 "---------------------------------------------------------\n");
931 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000932}
933
934// Playout Mode, background noise mode.
935// Receiver Frequency, playout frequency.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000936void APITest::TestPlayout(char receiveSide) {
937 AudioCodingModule* receiveACM;
938 AudioPlayoutMode* playoutMode = NULL;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000939 switch (receiveSide) {
940 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000941 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000942 playoutMode = &_playoutModeA;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000943 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000944 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000945 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000946 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000947 playoutMode = &_playoutModeB;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000948 break;
949 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000950 default:
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000951 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000952 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000953
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000954 int32_t receiveFreqHz = receiveACM->ReceiveFrequency();
955 int32_t playoutFreqHz = receiveACM->PlayoutFrequency();
956
957 CHECK_ERROR_MT(receiveFreqHz);
958 CHECK_ERROR_MT(playoutFreqHz);
959
niklase@google.com470e71d2011-07-07 08:21:25 +0000960
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000961 char playoutString[25];
962 switch (*playoutMode) {
963 case voice: {
964 *playoutMode = fax;
965 strncpy(playoutString, "FAX", 25);
966 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000967 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000968 case fax: {
969 *playoutMode = streaming;
970 strncpy(playoutString, "Streaming", 25);
971 break;
972 }
973 case streaming: {
974 *playoutMode = voice;
975 strncpy(playoutString, "Voice", 25);
976 break;
977 }
978 default:
979 *playoutMode = voice;
980 strncpy(playoutString, "Voice", 25);
981 }
982 CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
983 playoutString[24] = '\0';
984
985 if (!_randomTest) {
986 fprintf(stdout, "\n");
987 fprintf(stdout, "In Side %c\n", receiveSide);
988 fprintf(stdout, "---------------------------------\n");
989 fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
990 fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
991 fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000992 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000993}
994
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000995void APITest::TestSendVAD(char side) {
996 if (_randomTest) {
997 return;
998 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000999
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001000 bool* vad;
1001 bool* dtx;
1002 ACMVADMode* mode;
1003 Channel* myChannel;
1004 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +00001005
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001006 CodecInst myCodec;
1007 if (!_randomTest) {
1008 fprintf(stdout, "\n\n");
1009 fprintf(stdout, "-----------------------------------------------\n");
1010 fprintf(stdout, " Test VAD API\n");
1011 fprintf(stdout, "-----------------------------------------------\n");
1012 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001013
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001014 if (side == 'A') {
1015 AudioCodingModule::Codec(_codecCntrA, &myCodec);
1016 vad = &_sendVADA;
1017 dtx = &_sendDTXA;
1018 mode = &_sendVADModeA;
1019 myChannel = _channel_A2B;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001020 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001021 } else {
1022 AudioCodingModule::Codec(_codecCntrB, &myCodec);
1023 vad = &_sendVADB;
1024 dtx = &_sendDTXB;
1025 mode = &_sendVADModeB;
1026 myChannel = _channel_B2A;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001027 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001028 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001029
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001030 CheckVADStatus(side);
1031 if (!_randomTest) {
1032 fprintf(stdout, "\n\n");
1033 }
1034
1035 switch (*mode) {
1036 case VADNormal:
1037 *vad = true;
1038 *dtx = true;
1039 *mode = VADAggr;
1040 break;
1041 case VADLowBitrate:
1042 *vad = true;
1043 *dtx = true;
1044 *mode = VADVeryAggr;
1045 break;
1046 case VADAggr:
1047 *vad = true;
1048 *dtx = true;
1049 *mode = VADLowBitrate;
1050 break;
1051 case VADVeryAggr:
1052 *vad = false;
1053 *dtx = false;
1054 *mode = VADNormal;
1055 break;
1056 default:
1057 *mode = VADNormal;
1058 }
1059
1060 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
1061
1062 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1063 myChannel->ResetStats();
1064
1065 CheckVADStatus(side);
1066 if (!_randomTest) {
1067 fprintf(stdout, "\n");
1068 fprintf(stdout, "-----------------------------------------------\n");
1069 }
1070
1071 // Fault Test
1072 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
1073 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +00001074
1075}
1076
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001077void APITest::CurrentCodec(char side) {
1078 CodecInst myCodec;
1079 if (side == 'A') {
1080 _acmA->SendCodec(&myCodec);
1081 } else {
1082 _acmB->SendCodec(&myCodec);
1083 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001084
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001085 if (!_randomTest) {
1086 fprintf(stdout, "\n\n");
1087 fprintf(stdout, "Send codec in Side A\n");
1088 fprintf(stdout, "----------------------------\n");
1089 fprintf(stdout, "Name................. %s\n", myCodec.plname);
1090 fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
1091 fprintf(stdout, "Rate................. %d\n", myCodec.rate);
1092 fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
1093 fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
1094 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001095
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001096 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001097}
1098
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001099void APITest::ChangeCodec(char side) {
1100 CodecInst myCodec;
1101 AudioCodingModule* myACM;
1102 uint8_t* codecCntr;
1103 bool* thereIsEncoder;
1104 bool* vad;
1105 bool* dtx;
1106 ACMVADMode* mode;
1107 Channel* myChannel;
1108 // Reset and Wait
1109 if (!_randomTest) {
1110 fprintf(stdout, "Reset Encoder Side A \n");
1111 }
1112 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001113 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001114 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001115 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001116 WriteLockScoped wl(_apiTestRWLock);
1117 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001118 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001119 vad = &_sendVADA;
1120 dtx = &_sendDTXA;
1121 mode = &_sendVADModeA;
1122 myChannel = _channel_A2B;
1123 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001124 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001125 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001126 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001127 WriteLockScoped wl(_apiTestRWLock);
1128 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001129 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001130 vad = &_sendVADB;
1131 dtx = &_sendDTXB;
1132 mode = &_sendVADModeB;
1133 myChannel = _channel_B2A;
1134 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001135
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001136 myACM->ResetEncoder();
1137 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001138
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001139 // Register the next codec
1140 do {
1141 *codecCntr =
1142 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1143 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001144
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001145 if (*codecCntr == 0) {
1146 //printf("Initialize Sender Side A \n");
1147 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001148 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001149 *thereIsEncoder = false;
1150 }
1151 CHECK_ERROR_MT(myACM->InitializeSender());
1152 Wait(1000);
1153
1154 // After Initialization CN is lost, re-register them
1155 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1156 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1157 }
1158 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1159 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1160 }
1161 // VAD & DTX are disabled after initialization
1162 *vad = false;
1163 *dtx = false;
1164 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001165 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001166
1167 AudioCodingModule::Codec(*codecCntr, &myCodec);
1168 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1169 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1170 || !STR_CASE_CMP(myCodec.plname, "RED"));
1171
1172 if (!_randomTest) {
1173 fprintf(stdout,"\n=====================================================\n");
1174 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1175 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1176 }
1177 //std::cout<< std::flush;
1178
1179 // NO DTX for supe-wideband codec at this point
1180 if (myCodec.plfreq == 32000) {
1181 *dtx = false;
1182 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1183
1184 }
1185
1186 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1187 myChannel->ResetStats();
1188 {
1189 WriteLockScoped wl(_apiTestRWLock);
1190 *thereIsEncoder = true;
1191 }
1192 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001193}
1194
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001195} // namespace webrtc