blob: 1cdf6c753ae031142b109c8b6f71f2315deed3c0 [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
Peter Boström64c03662015-04-08 11:24:19 +0200250 _pullEventA = EventTimerWrapper::Create();
251 _pushEventA = EventTimerWrapper::Create();
252 _processEventA = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000253 _apiEventA = EventWrapper::Create();
254 // B
Peter Boström64c03662015-04-08 11:24:19 +0200255 _pullEventB = EventTimerWrapper::Create();
256 _pushEventB = EventTimerWrapper::Create();
257 _processEventB = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000258 _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.org38492c52015-03-22 14:41:46 +0000535 ThreadWrapper::CreateThread(PushAudioThreadA, this, "PushAudioThreadA");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000536 CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
537 // PULL
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000538 rtc::scoped_ptr<ThreadWrapper> myPullAudioThreadA =
tommi@webrtc.org38492c52015-03-22 14:41:46 +0000539 ThreadWrapper::CreateThread(PullAudioThreadA, this, "PullAudioThreadA");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000540 CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
541 // Process
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000542 rtc::scoped_ptr<ThreadWrapper> myProcessThreadA = ThreadWrapper::CreateThread(
tommi@webrtc.org38492c52015-03-22 14:41:46 +0000543 ProcessThreadA, this, "ProcessThreadA");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000544 CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
545 // API
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000546 rtc::scoped_ptr<ThreadWrapper> myAPIThreadA = ThreadWrapper::CreateThread(
tommi@webrtc.org38492c52015-03-22 14:41:46 +0000547 APIThreadA, this, "APIThreadA");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000548 CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
549 // B
550 // PUSH
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000551 rtc::scoped_ptr<ThreadWrapper> myPushAudioThreadB =
tommi@webrtc.org38492c52015-03-22 14:41:46 +0000552 ThreadWrapper::CreateThread(PushAudioThreadB, this, "PushAudioThreadB");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000553 CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
554 // PULL
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000555 rtc::scoped_ptr<ThreadWrapper> myPullAudioThreadB =
tommi@webrtc.org38492c52015-03-22 14:41:46 +0000556 ThreadWrapper::CreateThread(PullAudioThreadB, this, "PullAudioThreadB");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000557 CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
558 // Process
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000559 rtc::scoped_ptr<ThreadWrapper> myProcessThreadB = ThreadWrapper::CreateThread(
tommi@webrtc.org38492c52015-03-22 14:41:46 +0000560 ProcessThreadB, this, "ProcessThreadB");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000561 CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
562 // API
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000563 rtc::scoped_ptr<ThreadWrapper> myAPIThreadB = ThreadWrapper::CreateThread(
tommi@webrtc.org38492c52015-03-22 14:41:46 +0000564 APIThreadB, this, "APIThreadB");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000565 CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000566
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000567 //_apiEventA->StartTimer(true, 5000);
568 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000569
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000570 _processEventA->StartTimer(true, 10);
571 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000572
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000573 _pullEventA->StartTimer(true, 10);
574 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000575
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000576 _pushEventA->StartTimer(true, 10);
577 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000578
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000579 // Keep main thread waiting for sender/receiver
580 // threads to complete
581 EventWrapper* completeEvent = EventWrapper::Create();
582 uint64_t startTime = TickTime::MillisecondTimestamp();
583 uint64_t currentTime;
584 // Run test in 2 minutes (120000 ms).
585 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000586 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000587 //ReadLockScoped rl(_apiTestRWLock);
588 //fprintf(stderr, "\r%s", _movingDot);
589 }
590 //fflush(stderr);
591 completeEvent->Wait(50);
592 currentTime = TickTime::MillisecondTimestamp();
593 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000594
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000595 //completeEvent->Wait(0xFFFFFFFF);
596 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
597 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000598
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000599 myPushAudioThreadA->Stop();
600 myPullAudioThreadA->Stop();
601 myProcessThreadA->Stop();
602 myAPIThreadA->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000603
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000604 myPushAudioThreadB->Stop();
605 myPullAudioThreadB->Stop();
606 myProcessThreadB->Stop();
607 myAPIThreadB->Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000608}
609
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000610void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000611
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000612 bool dtxEnabled;
613 bool vadEnabled;
614 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000615
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000616 if (side == 'A') {
617 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
618 _acmA->RegisterVADCallback(NULL);
619 _vadCallbackA->Reset();
620 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000621
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000622 if (!_randomTest) {
623 if (_verbose) {
624 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
625 vadEnabled ? "ON" : "OFF", (int) vadMode);
626 Wait(5000);
627 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
628 } else {
629 Wait(5000);
630 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
631 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
632 (int) vadMode, _channel_A2B->BitRate());
633 }
634 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000635 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000636
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000637 if (dtxEnabled != _sendDTXA) {
638 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000639 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000640 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
641 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
642 }
643 if ((vadMode != _sendVADModeA) && vadEnabled) {
644 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
645 }
646 } else {
647 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
648
649 _acmB->RegisterVADCallback(NULL);
650 _vadCallbackB->Reset();
651 _acmB->RegisterVADCallback(_vadCallbackB);
652
653 if (!_randomTest) {
654 if (_verbose) {
655 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
656 vadEnabled ? "ON" : "OFF", (int) vadMode);
657 Wait(5000);
658 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
659 } else {
660 Wait(5000);
661 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
662 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
663 (int) vadMode, _channel_B2A->BitRate());
664 }
665 _vadCallbackB->PrintFrameTypes();
666 }
667
668 if (dtxEnabled != _sendDTXB) {
669 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
670 }
671 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
672 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
673 }
674 if ((vadMode != _sendVADModeB) && vadEnabled) {
675 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
676 }
677 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000678}
679
680// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000681void APITest::TestDelay(char side) {
682 AudioCodingModule* myACM;
683 Channel* myChannel;
684 int32_t* myMinDelay;
Peter Boström64c03662015-04-08 11:24:19 +0200685 EventTimerWrapper* myEvent = EventTimerWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000686
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000687 uint32_t inTimestamp = 0;
688 uint32_t outTimestamp = 0;
689 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000690
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000691 double averageEstimDelay = 0;
692 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000693
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000694 CircularBuffer estimDelayCB(100);
695 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000696
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000697 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000698 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000699 myChannel = _channel_B2A;
700 myMinDelay = &_minDelayA;
701 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000702 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000703 myChannel = _channel_A2B;
704 myMinDelay = &_minDelayB;
705 }
706
707 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
708
709 inTimestamp = myChannel->LastInTimestamp();
710 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
711
712 if (!_randomTest) {
713 myEvent->StartTimer(true, 30);
714 int n = 0;
715 int settlePoint = 5000;
716 while (n < settlePoint + 400) {
717 myEvent->Wait(1000);
718
719 inTimestamp = myChannel->LastInTimestamp();
720 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
721
722 //std::cout << outTimestamp << std::endl << std::flush;
723 estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
724 / ((double) myACM->ReceiveFrequency() / 1000.0);
725
726 estimDelayCB.Update(estimDelay);
727
728 estimDelayCB.ArithMean(averageEstimDelay);
729 //printf("\n %6.1f \n", estimDelay);
730 //std::cout << " " << std::flush;
731
732 if (_verbose) {
733 fprintf(stdout,
734 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
735 *myMinDelay, averageDelay, averageEstimDelay);
736 std::cout << " " << std::flush;
737 }
738 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
739 settlePoint = n;
740 }
741 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000742 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000743 myEvent->StopTimer();
744 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000745
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000746 if ((!_verbose) && (!_randomTest)) {
747 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000748 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000749 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000750
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000751 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000752
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000753 NetworkStatistics networkStat;
754 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000755
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000756 if (!_randomTest) {
757 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
758 fprintf(stdout, "--------------------------------------\n");
759 fprintf(stdout, "buffer-size............. %d\n",
760 networkStat.currentBufferSize);
761 fprintf(stdout, "Preferred buffer-size... %d\n",
762 networkStat.preferredBufferSize);
763 fprintf(stdout, "Peaky jitter mode........%d\n",
764 networkStat.jitterPeaksFound);
765 fprintf(stdout, "packet-size rate........ %d\n",
766 networkStat.currentPacketLossRate);
767 fprintf(stdout, "discard rate............ %d\n",
768 networkStat.currentDiscardRate);
769 fprintf(stdout, "expand rate............. %d\n",
770 networkStat.currentExpandRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000771 fprintf(stdout, "speech expand rate...... %d\n",
772 networkStat.currentSpeechExpandRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000773 fprintf(stdout, "Preemptive rate......... %d\n",
774 networkStat.currentPreemptiveRate);
775 fprintf(stdout, "Accelerate rate......... %d\n",
776 networkStat.currentAccelerateRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000777 fprintf(stdout, "Secondary decoded rate.. %d\n",
778 networkStat.currentSecondaryDecodedRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000779 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
780 fprintf(stdout, "Mean waiting time....... %d\n",
781 networkStat.meanWaitingTimeMs);
782 fprintf(stdout, "Median waiting time..... %d\n",
783 networkStat.medianWaitingTimeMs);
784 fprintf(stdout, "Min waiting time........ %d\n",
785 networkStat.minWaitingTimeMs);
786 fprintf(stdout, "Max waiting time........ %d\n",
787 networkStat.maxWaitingTimeMs);
788 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000789
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000790 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000791
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000792 if (!_randomTest) {
793 myEvent->Wait(500);
794 fprintf(stdout, "\n");
795 fprintf(stdout, "\n");
796 }
797 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000798}
799
800// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000801void APITest::TestRegisteration(char sendSide) {
802 AudioCodingModule* sendACM;
803 AudioCodingModule* receiveACM;
804 bool* thereIsDecoder;
805 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000806
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000807 if (!_randomTest) {
808 fprintf(stdout, "\n\n");
809 fprintf(stdout,
810 "---------------------------------------------------------\n");
811 fprintf(stdout, " Unregister/register Receive Codec\n");
812 fprintf(stdout,
813 "---------------------------------------------------------\n");
814 }
815
816 switch (sendSide) {
817 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000818 sendACM = _acmA.get();
819 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000820 thereIsDecoder = &_thereIsDecoderB;
821 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000822 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000823 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000824 sendACM = _acmB.get();
825 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000826 thereIsDecoder = &_thereIsDecoderA;
827 break;
828 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000829 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000830 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
831 sendSide);
832 exit(-1);
833 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000834
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000835 CodecInst myCodec;
836 if (sendACM->SendCodec(&myCodec) < 0) {
837 AudioCodingModule::Codec(_codecCntrA, &myCodec);
838 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000839
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000840 if (!_randomTest) {
841 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
842 fflush (stdout);
843 }
844 {
845 WriteLockScoped wl(_apiTestRWLock);
846 *thereIsDecoder = false;
847 }
848 //myEvent->Wait(20);
849 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
850 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000851
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000852 int currentPayload = myCodec.pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000853
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000854 if (!FixedPayloadTypeCodec(myCodec.plname)) {
855 int32_t i;
856 for (i = 0; i < 32; i++) {
857 if (!_payloadUsed[i]) {
858 if (!_randomTest) {
859 fprintf(stdout,
860 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000861 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000862 //myCodec.pltype = i + 96;
863 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
864 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
865 //myEvent->Wait(20);
866 //{
867 // WriteLockScoped wl(_apiTestRWLock);
868 // *thereIsDecoder = true;
869 //}
870 Wait(1000);
871
872 if (!_randomTest) {
873 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000874 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000875 //{
876 // WriteLockScoped wl(_apiTestRWLock);
877 // *thereIsDecoder = false;
878 //}
879 //myEvent->Wait(20);
880 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
881 Wait(1000);
882
883 myCodec.pltype = currentPayload;
884 if (!_randomTest) {
885 fprintf(stdout,
886 "Register receive codec with default Payload, AUDIO BACK.\n");
887 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000888 }
889 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000890 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000891 myEvent->Wait(20);
892 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000893 WriteLockScoped wl(_apiTestRWLock);
894 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000895 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000896 Wait(1000);
897
898 break;
899 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000900 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000901 if (i == 32) {
902 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
903 {
904 WriteLockScoped wl(_apiTestRWLock);
905 *thereIsDecoder = true;
906 }
907 }
908 } else {
909 if (!_randomTest) {
910 fprintf(stdout,
911 "Register receive codec with fixed Payload, AUDIO BACK.\n");
912 fflush (stdout);
913 }
914 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
915 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
916 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
917 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000918 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000919 WriteLockScoped wl(_apiTestRWLock);
920 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000921 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000922 }
923 delete myEvent;
924 if (!_randomTest) {
925 fprintf(stdout,
926 "---------------------------------------------------------\n");
927 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000928}
929
930// Playout Mode, background noise mode.
931// Receiver Frequency, playout frequency.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000932void APITest::TestPlayout(char receiveSide) {
933 AudioCodingModule* receiveACM;
934 AudioPlayoutMode* playoutMode = NULL;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000935 switch (receiveSide) {
936 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000937 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000938 playoutMode = &_playoutModeA;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000939 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000940 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000941 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000942 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000943 playoutMode = &_playoutModeB;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000944 break;
945 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000946 default:
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000947 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000948 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000949
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000950 int32_t receiveFreqHz = receiveACM->ReceiveFrequency();
951 int32_t playoutFreqHz = receiveACM->PlayoutFrequency();
952
953 CHECK_ERROR_MT(receiveFreqHz);
954 CHECK_ERROR_MT(playoutFreqHz);
955
niklase@google.com470e71d2011-07-07 08:21:25 +0000956
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000957 char playoutString[25];
958 switch (*playoutMode) {
959 case voice: {
960 *playoutMode = fax;
961 strncpy(playoutString, "FAX", 25);
962 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000963 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000964 case fax: {
965 *playoutMode = streaming;
966 strncpy(playoutString, "Streaming", 25);
967 break;
968 }
969 case streaming: {
970 *playoutMode = voice;
971 strncpy(playoutString, "Voice", 25);
972 break;
973 }
974 default:
975 *playoutMode = voice;
976 strncpy(playoutString, "Voice", 25);
977 }
978 CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
979 playoutString[24] = '\0';
980
981 if (!_randomTest) {
982 fprintf(stdout, "\n");
983 fprintf(stdout, "In Side %c\n", receiveSide);
984 fprintf(stdout, "---------------------------------\n");
985 fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
986 fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
987 fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000988 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000989}
990
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000991void APITest::TestSendVAD(char side) {
992 if (_randomTest) {
993 return;
994 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000995
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000996 bool* vad;
997 bool* dtx;
998 ACMVADMode* mode;
999 Channel* myChannel;
1000 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +00001001
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001002 CodecInst myCodec;
1003 if (!_randomTest) {
1004 fprintf(stdout, "\n\n");
1005 fprintf(stdout, "-----------------------------------------------\n");
1006 fprintf(stdout, " Test VAD API\n");
1007 fprintf(stdout, "-----------------------------------------------\n");
1008 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001009
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001010 if (side == 'A') {
1011 AudioCodingModule::Codec(_codecCntrA, &myCodec);
1012 vad = &_sendVADA;
1013 dtx = &_sendDTXA;
1014 mode = &_sendVADModeA;
1015 myChannel = _channel_A2B;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001016 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001017 } else {
1018 AudioCodingModule::Codec(_codecCntrB, &myCodec);
1019 vad = &_sendVADB;
1020 dtx = &_sendDTXB;
1021 mode = &_sendVADModeB;
1022 myChannel = _channel_B2A;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001023 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001024 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001025
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001026 CheckVADStatus(side);
1027 if (!_randomTest) {
1028 fprintf(stdout, "\n\n");
1029 }
1030
1031 switch (*mode) {
1032 case VADNormal:
1033 *vad = true;
1034 *dtx = true;
1035 *mode = VADAggr;
1036 break;
1037 case VADLowBitrate:
1038 *vad = true;
1039 *dtx = true;
1040 *mode = VADVeryAggr;
1041 break;
1042 case VADAggr:
1043 *vad = true;
1044 *dtx = true;
1045 *mode = VADLowBitrate;
1046 break;
1047 case VADVeryAggr:
1048 *vad = false;
1049 *dtx = false;
1050 *mode = VADNormal;
1051 break;
1052 default:
1053 *mode = VADNormal;
1054 }
1055
1056 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
1057
1058 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1059 myChannel->ResetStats();
1060
1061 CheckVADStatus(side);
1062 if (!_randomTest) {
1063 fprintf(stdout, "\n");
1064 fprintf(stdout, "-----------------------------------------------\n");
1065 }
1066
1067 // Fault Test
1068 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
1069 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +00001070
1071}
1072
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001073void APITest::CurrentCodec(char side) {
1074 CodecInst myCodec;
1075 if (side == 'A') {
1076 _acmA->SendCodec(&myCodec);
1077 } else {
1078 _acmB->SendCodec(&myCodec);
1079 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001080
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001081 if (!_randomTest) {
1082 fprintf(stdout, "\n\n");
1083 fprintf(stdout, "Send codec in Side A\n");
1084 fprintf(stdout, "----------------------------\n");
1085 fprintf(stdout, "Name................. %s\n", myCodec.plname);
1086 fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
1087 fprintf(stdout, "Rate................. %d\n", myCodec.rate);
1088 fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
1089 fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
1090 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001091
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001092 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001093}
1094
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001095void APITest::ChangeCodec(char side) {
1096 CodecInst myCodec;
1097 AudioCodingModule* myACM;
1098 uint8_t* codecCntr;
1099 bool* thereIsEncoder;
1100 bool* vad;
1101 bool* dtx;
1102 ACMVADMode* mode;
1103 Channel* myChannel;
1104 // Reset and Wait
1105 if (!_randomTest) {
1106 fprintf(stdout, "Reset Encoder Side A \n");
1107 }
1108 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001109 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001110 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001111 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001112 WriteLockScoped wl(_apiTestRWLock);
1113 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001114 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001115 vad = &_sendVADA;
1116 dtx = &_sendDTXA;
1117 mode = &_sendVADModeA;
1118 myChannel = _channel_A2B;
1119 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001120 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001121 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001122 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001123 WriteLockScoped wl(_apiTestRWLock);
1124 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001125 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001126 vad = &_sendVADB;
1127 dtx = &_sendDTXB;
1128 mode = &_sendVADModeB;
1129 myChannel = _channel_B2A;
1130 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001131
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001132 myACM->ResetEncoder();
1133 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001134
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001135 // Register the next codec
1136 do {
1137 *codecCntr =
1138 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1139 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001140
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001141 if (*codecCntr == 0) {
1142 //printf("Initialize Sender Side A \n");
1143 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001144 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001145 *thereIsEncoder = false;
1146 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001147 // After Initialization CN is lost, re-register them
1148 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1149 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1150 }
1151 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1152 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1153 }
1154 // VAD & DTX are disabled after initialization
1155 *vad = false;
1156 *dtx = false;
1157 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001158 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001159
1160 AudioCodingModule::Codec(*codecCntr, &myCodec);
1161 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1162 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1163 || !STR_CASE_CMP(myCodec.plname, "RED"));
1164
1165 if (!_randomTest) {
1166 fprintf(stdout,"\n=====================================================\n");
1167 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1168 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1169 }
1170 //std::cout<< std::flush;
1171
1172 // NO DTX for supe-wideband codec at this point
1173 if (myCodec.plfreq == 32000) {
1174 *dtx = false;
1175 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1176
1177 }
1178
1179 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1180 myChannel->ResetStats();
1181 {
1182 WriteLockScoped wl(_apiTestRWLock);
1183 *thereIsEncoder = true;
1184 }
1185 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001186}
1187
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001188} // namespace webrtc