blob: 81e26686862b653add07d5a82ed6268321811dd2 [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
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000011#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +000014#include <cctype>
15#include <iostream>
16#include <ostream>
17#include <string>
18
19#include "gtest/gtest.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020
21#include "APITest.h"
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000022#include "common_types.h"
23#include "engine_configurations.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000024#include "event_wrapper.h"
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000025#include "thread_wrapper.h"
kjellander@webrtc.org5490c712011-12-21 13:34:18 +000026#include "testsupport/fileutils.h"
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +000027#include "tick_util.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000028#include "trace.h"
29#include "utility.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000030
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000031namespace webrtc {
32
niklase@google.com470e71d2011-07-07 08:21:25 +000033#define TEST_DURATION_SEC 600
34
35#define NUMBER_OF_SENDER_TESTS 6
36
37#define MAX_FILE_NAME_LENGTH_BYTE 500
kjellander@webrtc.org5490c712011-12-21 13:34:18 +000038#define CHECK_THREAD_NULLITY(myThread, S) \
39 if(myThread != NULL) \
40 { \
41 unsigned int i; \
42 (myThread)->Start(i); \
43 } \
44 else \
45 { \
46 ADD_FAILURE() << S; \
47 }
niklase@google.com470e71d2011-07-07 08:21:25 +000048
niklase@google.com470e71d2011-07-07 08:21:25 +000049
50void
51APITest::Wait(WebRtc_UWord32 waitLengthMs)
52{
53 if(_randomTest)
54 {
55 return;
56 }
57 else
58 {
59 EventWrapper* myEvent = EventWrapper::Create();
60 myEvent->Wait(waitLengthMs);
61 delete myEvent;
62 return;
63 }
64}
65
66
67
68APITest::APITest():
69_acmA(NULL),
70_acmB(NULL),
71_channel_A2B(NULL),
72_channel_B2A(NULL),
73_writeToFile(true),
74_pullEventA(NULL),
75_pushEventA(NULL),
76_processEventA(NULL),
77_apiEventA(NULL),
78_pullEventB(NULL),
79_pushEventB(NULL),
80_processEventB(NULL),
81_apiEventB(NULL),
82_codecCntrA(0),
83_codecCntrB(0),
niklase@google.com470e71d2011-07-07 08:21:25 +000084_thereIsEncoderA(false),
85_thereIsEncoderB(false),
86_thereIsDecoderA(false),
87_thereIsDecoderB(false),
88_sendVADA(false),
89_sendDTXA(false),
90_sendVADModeA(VADNormal),
91_sendVADB(false),
92_sendDTXB(false),
93_sendVADModeB(VADNormal),
94_minDelayA(0),
95_minDelayB(0),
96_dotPositionA(0),
97_dotMoveDirectionA(1),
98_dotPositionB(39),
99_dotMoveDirectionB(-1),
100_dtmfCallback(NULL),
101_vadCallbackA(NULL),
102_vadCallbackB(NULL),
103_apiTestRWLock(*RWLockWrapper::CreateRWLock()),
104_randomTest(false),
105_testNumA(0),
106_testNumB(1)
107{
108 int n;
109 for( n = 0; n < 32; n++)
110 {
111 _payloadUsed[n] = false;
112 }
113
114 for(n = 0; n < 3; n++)
115 {
116 _receiveVADActivityA[n] = 0;
117 _receiveVADActivityB[n] = 0;
118 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000119
niklase@google.com470e71d2011-07-07 08:21:25 +0000120 _movingDot[40] = '\0';
121
122 for(int n = 0; n <40; n++)
123 {
124 _movingDot[n] = ' ';
125 }
126}
127
128APITest::~APITest()
129{
130 DESTROY_ACM(_acmA);
131 DESTROY_ACM(_acmB);
132
133 DELETE_POINTER(_channel_A2B);
134 DELETE_POINTER(_channel_B2A);
135
136 DELETE_POINTER(_pushEventA);
137 DELETE_POINTER(_pullEventA);
138 DELETE_POINTER(_processEventA);
139 DELETE_POINTER(_apiEventA);
140
141 DELETE_POINTER(_pushEventB);
142 DELETE_POINTER(_pullEventB);
143 DELETE_POINTER(_processEventB);
144 DELETE_POINTER(_apiEventB);
145
146 _inFileA.Close();
147 _outFileA.Close();
148
149 _inFileB.Close();
150 _outFileB.Close();
151
152 DELETE_POINTER(_dtmfCallback);
153 DELETE_POINTER(_vadCallbackA);
154 DELETE_POINTER(_vadCallbackB);
155
156 delete &_apiTestRWLock;
157}
158
159
160
161//WebRtc_Word16
162//APITest::SetInFile(char* fileName, WebRtc_UWord16 frequencyHz)
163//{
164// return _inFile.Open(fileName, frequencyHz, "rb");
165//}
166//
167//WebRtc_Word16
168//APITest::SetOutFile(char* fileName, WebRtc_UWord16 frequencyHz)
169//{
170// return _outFile.Open(fileName, frequencyHz, "wb");
171//}
172
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000173WebRtc_Word16
niklase@google.com470e71d2011-07-07 08:21:25 +0000174APITest::SetUp()
175{
176 _acmA = AudioCodingModule::Create(1);
177 _acmB = AudioCodingModule::Create(2);
178
179 CodecInst dummyCodec;
180 int lastPayloadType = 0;
181
182 WebRtc_Word16 numCodecs = _acmA->NumberOfCodecs();
183 for(WebRtc_UWord8 n = 0; n < numCodecs; n++)
184 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000185 AudioCodingModule::Codec(n, &dummyCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000186 if((STR_CASE_CMP(dummyCodec.plname, "CN") == 0) &&
187 (dummyCodec.plfreq == 32000))
188 {
189 continue;
190 }
191
192 printf("Register Receive Codec %s ", dummyCodec.plname);
193
194 if((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname))
195 {
196 // Check registration with an already occupied payload type
197 int currentPayloadType = dummyCodec.pltype;
198 dummyCodec.pltype = 97; //lastPayloadType;
199 CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
200 dummyCodec.pltype = currentPayloadType;
201 }
202
203 if((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname))
204 {
205 // test if re-registration works;
206 CodecInst nextCodec;
207 int currentPayloadType = dummyCodec.pltype;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000208 AudioCodingModule::Codec(n + 1, &nextCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000209 dummyCodec.pltype = nextCodec.pltype;
210 if(!FixedPayloadTypeCodec(nextCodec.plname))
211 {
212 _acmB->RegisterReceiveCodec(dummyCodec);
213 }
214 dummyCodec.pltype = currentPayloadType;
215 }
216
217 if((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname))
218 {
219 // test if un-registration works;
220 CodecInst nextCodec;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000221 AudioCodingModule::Codec(n + 1, &nextCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000222 nextCodec.pltype = dummyCodec.pltype;
223 if(!FixedPayloadTypeCodec(nextCodec.plname))
224 {
225 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
226 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
227 }
228 }
229
230
231 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
232 printf(" side A done!");
233 CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
234 printf(" side B done!\n");
235
236 if(!strcmp(dummyCodec.plname, "CN"))
237 {
238 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
239 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
240 }
241 lastPayloadType = dummyCodec.pltype;
242 if((lastPayloadType >= 96) && (lastPayloadType <= 127))
243 {
244 _payloadUsed[lastPayloadType - 96] = true;
245 }
246 }
247 _thereIsDecoderA = true;
248 _thereIsDecoderB = true;
249
250 // Register Send Codec
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000251 AudioCodingModule::Codec((WebRtc_UWord8)_codecCntrA, &dummyCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000252 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
253 _thereIsEncoderA = true;
254 //
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000255 AudioCodingModule::Codec((WebRtc_UWord8)_codecCntrB, &dummyCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000256 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
257 _thereIsEncoderB = true;
258
niklase@google.com470e71d2011-07-07 08:21:25 +0000259 WebRtc_UWord16 frequencyHz;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000260
niklase@google.com470e71d2011-07-07 08:21:25 +0000261 printf("\n\nAPI Test\n");
262 printf("========\n");
263 printf("Hit enter to accept the default values indicated in []\n\n");
264
265 //--- Input A
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000266 std::string file_name =
267 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
niklase@google.com470e71d2011-07-07 08:21:25 +0000268 frequencyHz = 32000;
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000269 printf("Enter input file at side A [%s]: ", file_name.c_str());
270 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
271 _inFileA.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000272
273 //--- Output A
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000274 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
275 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
276 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
277 _outFileA.Open(out_file_a, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000278
279 //--- Input B
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000280 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
281 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
282 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
283 _inFileB.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000284
285 //--- Output B
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000286 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
287 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
288 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
289 _outFileB.Open(out_file_b, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000290
291 //--- Set A-to-B channel
292 _channel_A2B = new Channel(2);
293 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
294 _channel_A2B->RegisterReceiverACM(_acmB);
295
296 //--- Set B-to-A channel
297 _channel_B2A = new Channel(1);
298 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
299 _channel_B2A->RegisterReceiverACM(_acmA);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000300
niklase@google.com470e71d2011-07-07 08:21:25 +0000301 //--- EVENT TIMERS
302 // A
303 _pullEventA = EventWrapper::Create();
304 _pushEventA = EventWrapper::Create();
305 _processEventA = EventWrapper::Create();
306 _apiEventA = EventWrapper::Create();
307 // B
308 _pullEventB = EventWrapper::Create();
309 _pushEventB = EventWrapper::Create();
310 _processEventB = EventWrapper::Create();
311 _apiEventB = EventWrapper::Create();
312
313 //--- I/O params
314 // A
315 _outFreqHzA = _outFileA.SamplingFrequency();
316 // B
317 _outFreqHzB = _outFileB.SamplingFrequency();
318
319
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000320 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
niklase@google.com470e71d2011-07-07 08:21:25 +0000321
322 char print[11];
323
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +0000324 // Create a trace file.
325 Trace::CreateTrace();
326 Trace::SetTraceFile((webrtc::test::OutputPath() +
327 "acm_api_trace.txt").c_str());
328
niklase@google.com470e71d2011-07-07 08:21:25 +0000329 printf("\nRandom Test (y/n)?");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000330 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 print[10] = '\0';
332 if(strstr(print, "y") != NULL)
333 {
334 _randomTest = true;
335 _verbose = false;
336 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000337 }
338 else
339 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 _randomTest = false;
341 printf("\nPrint Tests (y/n)? ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000342 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 print[10] = '\0';
344 if(strstr(print, "y") == NULL)
345 {
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000346 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000347 _verbose = false;
348 }
349 }
350
351#ifdef WEBRTC_DTMF_DETECTION
352 _dtmfCallback = new DTMFDetector;
353#endif
354 _vadCallbackA = new VADCallback;
355 _vadCallbackB = new VADCallback;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000356
niklase@google.com470e71d2011-07-07 08:21:25 +0000357 return 0;
358}
359
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000360bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000361APITest::PushAudioThreadA(void* obj)
362{
363 return static_cast<APITest*>(obj)->PushAudioRunA();
364}
365
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000366bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000367APITest::PushAudioThreadB(void* obj)
368{
369 return static_cast<APITest*>(obj)->PushAudioRunB();
370}
371
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000372bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000373APITest::PullAudioThreadA(void* obj)
374{
375 return static_cast<APITest*>(obj)->PullAudioRunA();
376}
377
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000378bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000379APITest::PullAudioThreadB(void* obj)
380{
381 return static_cast<APITest*>(obj)->PullAudioRunB();
382}
383
384bool
385APITest::ProcessThreadA(void* obj)
386{
387 return static_cast<APITest*>(obj)->ProcessRunA();
388}
389
390bool
391APITest::ProcessThreadB(void* obj)
392{
393 return static_cast<APITest*>(obj)->ProcessRunB();
394}
395
396bool
397APITest::APIThreadA(void* obj)
398{
399 return static_cast<APITest*>(obj)->APIRunA();
400}
401
402bool
403APITest::APIThreadB(void* obj)
404{
405 return static_cast<APITest*>(obj)->APIRunB();
406}
407
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000408bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000409APITest::PullAudioRunA()
410{
411 _pullEventA->Wait(100);
412 AudioFrame audioFrame;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000413 if(_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame) < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000414 {
415 bool thereIsDecoder;
416 {
417 ReadLockScoped rl(_apiTestRWLock);
418 thereIsDecoder = _thereIsDecoderA;
419 }
420 if(thereIsDecoder)
421 {
422 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
423 }
424 }
425 else
426 {
427 if(_writeToFile)
428 {
429 _outFileA.Write10MsData(audioFrame);
430 }
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000431 _receiveVADActivityA[(int)audioFrame.vad_activity_]++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000432 }
433 return true;
434}
435
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000436bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000437APITest::PullAudioRunB()
438{
439 _pullEventB->Wait(100);
440 AudioFrame audioFrame;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000441 if(_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame) < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000442 {
443 bool thereIsDecoder;
444 {
445 ReadLockScoped rl(_apiTestRWLock);
446 thereIsDecoder = _thereIsDecoderB;
447 }
448 if(thereIsDecoder)
449 {
450 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
451 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
452 }
453 }
454 else
455 {
456 if(_writeToFile)
457 {
458 _outFileB.Write10MsData(audioFrame);
459 }
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000460 _receiveVADActivityB[(int)audioFrame.vad_activity_]++;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000461 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000462 return true;
463}
464
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000465bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000466APITest::PushAudioRunA()
467{
468 _pushEventA->Wait(100);
469 AudioFrame audioFrame;
470 _inFileA.Read10MsData(audioFrame);
471 if(_acmA->Add10MsData(audioFrame) < 0)
472 {
473 bool thereIsEncoder;
474 {
475 ReadLockScoped rl(_apiTestRWLock);
476 thereIsEncoder = _thereIsEncoderA;
477 }
478 if(thereIsEncoder)
479 {
480 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
481 }
482 }
483 return true;
484}
485
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000486bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000487APITest::PushAudioRunB()
488{
489 _pushEventB->Wait(100);
490 AudioFrame audioFrame;
491 _inFileB.Read10MsData(audioFrame);
492 if(_acmB->Add10MsData(audioFrame) < 0)
493 {
494 bool thereIsEncoder;
495 {
496 ReadLockScoped rl(_apiTestRWLock);
497 thereIsEncoder = _thereIsEncoderB;
498 }
499
500 if(thereIsEncoder)
501 {
502 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
503 }
504 }
505
506 return true;
507}
508
509bool
510APITest::ProcessRunA()
511{
512 _processEventA->Wait(100);
513 if(_acmA->Process() < 0)
514 {
515 // do not print error message if there is no encoder
516 bool thereIsEncoder;
517 {
518 ReadLockScoped rl(_apiTestRWLock);
519 thereIsEncoder = _thereIsEncoderA;
520 }
521
522 if(thereIsEncoder)
523 {
524 fprintf(stderr, "\n>>>>> Process Failed at A <<<<<\n");
525 }
526 }
527 return true;
528}
529
530bool
531APITest::ProcessRunB()
532{
533 _processEventB->Wait(100);
534 if(_acmB->Process() < 0)
535 {
536 bool thereIsEncoder;
537 {
538 ReadLockScoped rl(_apiTestRWLock);
539 thereIsEncoder = _thereIsEncoderB;
540 }
541 if(thereIsEncoder)
542 {
543 fprintf(stderr, "\n>>>>> Process Failed at B <<<<<\n");
544 }
545 }
546 return true;
547}
548
549/*/
550 *
551 * In side A we test the APIs which are related to sender Side.
552 *
553/*/
554
555
556void
557APITest::RunTest(char thread)
558{
559 int testNum;
560 {
561 WriteLockScoped cs(_apiTestRWLock);
562 if(thread == 'A')
563 {
564 _testNumA = (_testNumB + 1 + (rand() % 6)) % 7;
565 testNum = _testNumA;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000566
niklase@google.com470e71d2011-07-07 08:21:25 +0000567 _movingDot[_dotPositionA] = ' ';
568 if(_dotPositionA == 0)
569 {
570 _dotMoveDirectionA = 1;
571 }
572 if(_dotPositionA == 19)
573 {
574 _dotMoveDirectionA = -1;
575 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000576 _dotPositionA += _dotMoveDirectionA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000577 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0)? '>':'<';
578 }
579 else
580 {
581 _testNumB = (_testNumA + 1 + (rand() % 6)) % 7;
582 testNum = _testNumB;
583
584 _movingDot[_dotPositionB] = ' ';
585 if(_dotPositionB == 20)
586 {
587 _dotMoveDirectionB = 1;
588 }
589 if(_dotPositionB == 39)
590 {
591 _dotMoveDirectionB = -1;
592 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000593 _dotPositionB += _dotMoveDirectionB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000594 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0)? '>':'<';
595 }
596 //fprintf(stderr, "%c: %d \n", thread, testNum);
597 //fflush(stderr);
598 }
599 switch(testNum)
600 {
601 case 0:
602 CurrentCodec('A');
603 ChangeCodec('A');
604 break;
605 case 1:
606 TestPlayout('B');
607 break;
608 case 2:
609 if(!_randomTest)
610 {
611 fprintf(stdout, "\nTesting Delay ...\n");
612 }
613 TestDelay('A');
614 break;
615 case 3:
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000616 TestSendVAD('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000617 break;
618 case 4:
619 TestRegisteration('A');
620 break;
621 case 5:
622 TestReceiverVAD('A');
623 break;
624 case 6:
625#ifdef WEBRTC_DTMF_DETECTION
626 LookForDTMF('A');
627#endif
628 break;
629 default:
630 fprintf(stderr, "Wrong Test Number\n");
631 getchar();
632 exit(1);
633 }
634}
635
636
637
638bool
639APITest::APIRunA()
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000640{
niklase@google.com470e71d2011-07-07 08:21:25 +0000641 _apiEventA->Wait(50);
642
643 bool randomTest;
644 {
645 ReadLockScoped rl(_apiTestRWLock);
646 randomTest = _randomTest;
647 }
648 if(randomTest)
649 {
650 RunTest('A');
651 }
652 else
653 {
654 CurrentCodec('A');
655 ChangeCodec('A');
656 TestPlayout('B');
657 if(_codecCntrA == 0)
658 {
659 fprintf(stdout, "\nTesting Delay ...\n");
660 TestDelay('A');
661 }
662 // VAD TEST
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000663 TestSendVAD('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000664 TestRegisteration('A');
665 TestReceiverVAD('A');
666#ifdef WEBRTC_DTMF_DETECTION
667 LookForDTMF('A');
668#endif
669 }
670 return true;
671}
672
673bool
674APITest::APIRunB()
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000675{
niklase@google.com470e71d2011-07-07 08:21:25 +0000676 _apiEventB->Wait(50);
677 bool randomTest;
678 {
679 ReadLockScoped rl(_apiTestRWLock);
680 randomTest = _randomTest;
681 }
682 //_apiEventB->Wait(2000);
683 if(randomTest)
684 {
685 RunTest('B');
686 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000687
niklase@google.com470e71d2011-07-07 08:21:25 +0000688 return true;
689}
690
691void
692APITest::Perform()
693{
694 SetUp();
695
696 //--- THREADS
697 // A
698 // PUSH
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000699 ThreadWrapper* myPushAudioThreadA = ThreadWrapper::CreateThread(PushAudioThreadA,
niklase@google.com470e71d2011-07-07 08:21:25 +0000700 this, kNormalPriority, "PushAudioThreadA");
701 CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
702 // PULL
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000703 ThreadWrapper* myPullAudioThreadA = ThreadWrapper::CreateThread(PullAudioThreadA,
niklase@google.com470e71d2011-07-07 08:21:25 +0000704 this, kNormalPriority, "PullAudioThreadA");
705 CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
706 // Process
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000707 ThreadWrapper* myProcessThreadA = ThreadWrapper::CreateThread(ProcessThreadA,
niklase@google.com470e71d2011-07-07 08:21:25 +0000708 this, kNormalPriority, "ProcessThreadA");
709 CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000710 // API
711 ThreadWrapper* myAPIThreadA = ThreadWrapper::CreateThread(APIThreadA,
niklase@google.com470e71d2011-07-07 08:21:25 +0000712 this, kNormalPriority, "APIThreadA");
713 CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
714 // B
715 // PUSH
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000716 ThreadWrapper* myPushAudioThreadB = ThreadWrapper::CreateThread(PushAudioThreadB,
niklase@google.com470e71d2011-07-07 08:21:25 +0000717 this, kNormalPriority, "PushAudioThreadB");
718 CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
719 // PULL
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000720 ThreadWrapper* myPullAudioThreadB = ThreadWrapper::CreateThread(PullAudioThreadB,
niklase@google.com470e71d2011-07-07 08:21:25 +0000721 this, kNormalPriority, "PullAudioThreadB");
722 CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
723 // Process
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000724 ThreadWrapper* myProcessThreadB = ThreadWrapper::CreateThread(ProcessThreadB,
niklase@google.com470e71d2011-07-07 08:21:25 +0000725 this, kNormalPriority, "ProcessThreadB");
726 CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
727 // API
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000728 ThreadWrapper* myAPIThreadB = ThreadWrapper::CreateThread(APIThreadB,
niklase@google.com470e71d2011-07-07 08:21:25 +0000729 this, kNormalPriority, "APIThreadB");
730 CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000731
niklase@google.com470e71d2011-07-07 08:21:25 +0000732
733 //_apiEventA->StartTimer(true, 5000);
734 //_apiEventB->StartTimer(true, 5000);
735
736 _processEventA->StartTimer(true, 10);
737 _processEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000738
niklase@google.com470e71d2011-07-07 08:21:25 +0000739 _pullEventA->StartTimer(true, 10);
740 _pullEventB->StartTimer(true, 10);
741
742 _pushEventA->StartTimer(true, 10);
743 _pushEventB->StartTimer(true, 10);
744
745 // Keep main thread waiting for sender/receiver
746 // threads to complete
747 EventWrapper* completeEvent = EventWrapper::Create();
748 WebRtc_UWord64 startTime = TickTime::MillisecondTimestamp();
749 WebRtc_UWord64 currentTime;
750 do
751 {
752 {
753 //ReadLockScoped rl(_apiTestRWLock);
754 //fprintf(stderr, "\r%s", _movingDot);
755 }
756 //fflush(stderr);
757 completeEvent->Wait(50);
758 currentTime = TickTime::MillisecondTimestamp();
759 } while((currentTime - startTime) < 120000); // Run test in 2 minutes (120000 ms)
760
761 //completeEvent->Wait(0xFFFFFFFF);//(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
762 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000763
niklase@google.com470e71d2011-07-07 08:21:25 +0000764 myPushAudioThreadA->Stop();
765 myPullAudioThreadA->Stop();
766 myProcessThreadA->Stop();
767 myAPIThreadA->Stop();
768
769 delete myPushAudioThreadA;
770 delete myPullAudioThreadA;
771 delete myProcessThreadA;
772 delete myAPIThreadA;
773
774
775 myPushAudioThreadB->Stop();
776 myPullAudioThreadB->Stop();
777 myProcessThreadB->Stop();
778 myAPIThreadB->Stop();
779
780 delete myPushAudioThreadB;
781 delete myPullAudioThreadB;
782 delete myProcessThreadB;
783 delete myAPIThreadB;
784}
785
786
787void
788APITest::CheckVADStatus(char side)
789{
790
791 bool dtxEnabled;
792 bool vadEnabled;
793 ACMVADMode vadMode;
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000794
niklase@google.com470e71d2011-07-07 08:21:25 +0000795 if(side == 'A')
796 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000797 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000798 _acmA->RegisterVADCallback(NULL);
799 _vadCallbackA->Reset();
800 _acmA->RegisterVADCallback(_vadCallbackA);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000801
niklase@google.com470e71d2011-07-07 08:21:25 +0000802 if(!_randomTest)
803 {
804 if(_verbose)
805 {
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000806 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d",
niklase@google.com470e71d2011-07-07 08:21:25 +0000807 dtxEnabled? "ON":"OFF",
808 vadEnabled? "ON":"OFF",
809 (int)vadMode);
810 Wait(5000);
811 fprintf(stdout, " => bit-rate %3.0f kbps\n",
812 _channel_A2B->BitRate());
813 }
814 else
815 {
816 Wait(5000);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000817 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
niklase@google.com470e71d2011-07-07 08:21:25 +0000818 dtxEnabled? "ON":"OFF",
819 vadEnabled? "ON":"OFF",
820 (int)vadMode,
821 _channel_A2B->BitRate());
822 }
823 _vadCallbackA->PrintFrameTypes();
824 }
825
826 if(dtxEnabled != _sendDTXA)
827 {
828 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
829 }
830 if((vadEnabled != _sendVADA) && (!dtxEnabled))
831 {
832 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
833 }
834 if((vadMode != _sendVADModeA) && vadEnabled)
835 {
836 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
837 }
838 }
839 else
840 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000841 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000842
843 _acmB->RegisterVADCallback(NULL);
844 _vadCallbackB->Reset();
845 _acmB->RegisterVADCallback(_vadCallbackB);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000846
niklase@google.com470e71d2011-07-07 08:21:25 +0000847 if(!_randomTest)
848 {
849 if(_verbose)
850 {
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000851 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d",
niklase@google.com470e71d2011-07-07 08:21:25 +0000852 dtxEnabled? "ON":"OFF",
853 vadEnabled? "ON":"OFF",
854 (int)vadMode);
855 Wait(5000);
856 fprintf(stdout, " => bit-rate %3.0f kbps\n",
857 _channel_B2A->BitRate());
858 }
859 else
860 {
861 Wait(5000);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000862 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
niklase@google.com470e71d2011-07-07 08:21:25 +0000863 dtxEnabled? "ON":"OFF",
864 vadEnabled? "ON":"OFF",
865 (int)vadMode,
866 _channel_B2A->BitRate());
867 }
868 _vadCallbackB->PrintFrameTypes();
869 }
870
871 if(dtxEnabled != _sendDTXB)
872 {
873 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
874 }
875 if((vadEnabled != _sendVADB) && (!dtxEnabled))
876 {
877 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
878 }
879 if((vadMode != _sendVADModeB) && vadEnabled)
880 {
881 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
882 }
883 }
884}
885
886// Set Min delay, get delay, playout timestamp
887void
888APITest::TestDelay(char side)
889{
890 AudioCodingModule* myACM;
891 Channel* myChannel;
892 WebRtc_Word32* myMinDelay;
893 EventWrapper* myEvent = EventWrapper::Create();
894
895 WebRtc_UWord32 inTimestamp = 0;
896 WebRtc_UWord32 outTimestamp = 0;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000897 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000898
899 double averageEstimDelay = 0;
900 double averageDelay = 0;
901
902 CircularBuffer estimDelayCB(100);
niklase@google.com470e71d2011-07-07 08:21:25 +0000903 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000904
905 if(side == 'A')
906 {
907 myACM = _acmA;
908 myChannel = _channel_B2A;
909 myMinDelay = &_minDelayA;
910 }
911 else
912 {
913 myACM = _acmB;
914 myChannel = _channel_A2B;
915 myMinDelay = &_minDelayB;
916 }
917
918
919 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
920
921
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000922 inTimestamp = myChannel->LastInTimestamp();
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000923 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
niklase@google.com470e71d2011-07-07 08:21:25 +0000924
925 if(!_randomTest)
926 {
927 myEvent->StartTimer(true, 30);
928 int n = 0;
929 int settlePoint = 5000;
930 while(n < settlePoint + 400)
931 {
932 myEvent->Wait(1000);
933
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000934 inTimestamp = myChannel->LastInTimestamp();
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000935 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
niklase@google.com470e71d2011-07-07 08:21:25 +0000936
937 //std::cout << outTimestamp << std::endl << std::flush;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000938 estimDelay = (double)((WebRtc_UWord32)(inTimestamp - outTimestamp)) /
niklase@google.com470e71d2011-07-07 08:21:25 +0000939 ((double)myACM->ReceiveFrequency() / 1000.0);
940
941 estimDelayCB.Update(estimDelay);
942
943 estimDelayCB.ArithMean(averageEstimDelay);
944 //printf("\n %6.1f \n", estimDelay);
945 //std::cout << " " << std::flush;
946
niklase@google.com470e71d2011-07-07 08:21:25 +0000947 if(_verbose)
948 {
949 fprintf(stdout, "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
950 *myMinDelay, averageDelay, averageEstimDelay);
951 std::cout << " " << std::flush;
952 }
953 if((averageDelay > *myMinDelay) && (n < settlePoint))
954 {
955 settlePoint = n;
956 }
957 n++;
958 }
959 myEvent->StopTimer();
960 }
961
962 if((!_verbose) && (!_randomTest))
963 {
964 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
965 *myMinDelay, averageDelay, averageEstimDelay);
966 }
967
968 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000969
niklase@google.com470e71d2011-07-07 08:21:25 +0000970 ACMNetworkStatistics networkStat;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000971 CHECK_ERROR_MT(myACM->NetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000972
973 if(!_randomTest)
974 {
975 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
976 fprintf(stdout, "--------------------------------------\n");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000977 fprintf(stdout, "buffer-size............. %d\n", networkStat.currentBufferSize);
henrik.lundin@webrtc.orgd4398702012-01-04 13:09:55 +0000978 fprintf(stdout, "Preferred buffer-size... %d\n", networkStat.preferredBufferSize);
979 fprintf(stdout, "Peaky jitter mode........%d\n", networkStat.jitterPeaksFound);
niklase@google.com470e71d2011-07-07 08:21:25 +0000980 fprintf(stdout, "packet-size rate........ %d\n", networkStat.currentPacketLossRate);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000981 fprintf(stdout, "discard rate............ %d\n", networkStat.currentDiscardRate);
982 fprintf(stdout, "expand rate............. %d\n", networkStat.currentExpandRate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000983 fprintf(stdout, "Preemptive rate......... %d\n", networkStat.currentPreemptiveRate);
984 fprintf(stdout, "Accelerate rate......... %d\n", networkStat.currentAccelerateRate);
henrik.lundin@webrtc.orgd4398702012-01-04 13:09:55 +0000985 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
986 fprintf(stdout, "Mean waiting time....... %d\n", networkStat.meanWaitingTimeMs);
987 fprintf(stdout, "Median waiting time..... %d\n", networkStat.medianWaitingTimeMs);
henrik.lundin@webrtc.org053c7992012-01-12 14:16:44 +0000988 fprintf(stdout, "Min waiting time........ %d\n", networkStat.minWaitingTimeMs);
henrik.lundin@webrtc.orgd4398702012-01-04 13:09:55 +0000989 fprintf(stdout, "Max waiting time........ %d\n", networkStat.maxWaitingTimeMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000990 }
991
992 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
993
994 if(!_randomTest)
995 {
996 myEvent->Wait(500);
997 fprintf(stdout, "\n");
998 fprintf(stdout, "\n");
999 }
1000 delete myEvent;
1001}
1002
1003// Unregister a codec & register again.
1004void
1005APITest::TestRegisteration(char sendSide)
1006{
1007 AudioCodingModule* sendACM;
1008 AudioCodingModule* receiveACM;
1009 bool* thereIsDecoder;
1010 EventWrapper* myEvent = EventWrapper::Create();
1011
1012 if(!_randomTest)
1013 {
1014 fprintf(stdout, "\n\n");
1015 fprintf(stdout, "---------------------------------------------------------\n");
1016 fprintf(stdout, " Unregister/register Receive Codec\n");
1017 fprintf(stdout, "---------------------------------------------------------\n");
1018 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001019
niklase@google.com470e71d2011-07-07 08:21:25 +00001020 switch(sendSide)
1021 {
1022 case 'A':
1023 {
1024 sendACM = _acmA;
1025 receiveACM = _acmB;
1026 thereIsDecoder = &_thereIsDecoderB;
1027 break;
1028 }
1029 case 'B':
1030 {
1031 sendACM = _acmB;
1032 receiveACM = _acmA;
1033 thereIsDecoder = &_thereIsDecoderA;
1034 break;
1035 }
1036 default:
1037 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n", sendSide);
1038 exit(-1);
1039 }
1040
1041 CodecInst myCodec;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001042 if(sendACM->SendCodec(&myCodec) < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +00001043 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001044 AudioCodingModule::Codec(_codecCntrA, &myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001045 }
1046
1047 if(!_randomTest)
1048 {
1049 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
1050 fflush(stdout);
1051 }
1052 {
1053 WriteLockScoped wl(_apiTestRWLock);
1054 *thereIsDecoder = false;
1055 }
1056 //myEvent->Wait(20);
1057 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
1058 Wait(1000);
1059
1060 int currentPayload = myCodec.pltype;
1061
1062 if(!FixedPayloadTypeCodec(myCodec.plname))
1063 {
1064 WebRtc_Word32 i;
1065 for(i = 0; i < 32; i++)
1066 {
1067 if(!_payloadUsed[i])
1068 {
1069 if(!_randomTest)
1070 {
1071 fprintf(stdout, "Register receive codec with new Payload, AUDIO BACK.\n");
1072 }
1073 //myCodec.pltype = i + 96;
1074 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1075 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
1076 //myEvent->Wait(20);
1077 //{
1078 // WriteLockScoped wl(_apiTestRWLock);
1079 // *thereIsDecoder = true;
1080 //}
1081 Wait(1000);
1082
1083 if(!_randomTest)
1084 {
1085 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
1086 }
1087 //{
1088 // WriteLockScoped wl(_apiTestRWLock);
1089 // *thereIsDecoder = false;
1090 //}
1091 //myEvent->Wait(20);
1092 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
1093 Wait(1000);
1094
1095 myCodec.pltype = currentPayload;
1096 if(!_randomTest)
1097 {
1098 fprintf(stdout, "Register receive codec with default Payload, AUDIO BACK.\n");
1099 fflush(stdout);
1100 }
1101 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1102 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
1103 myEvent->Wait(20);
1104 {
1105 WriteLockScoped wl(_apiTestRWLock);
1106 *thereIsDecoder = true;
1107 }
1108 Wait(1000);
1109
1110 break;
1111 }
1112 }
1113 if(i == 32)
1114 {
1115 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1116 {
1117 WriteLockScoped wl(_apiTestRWLock);
1118 *thereIsDecoder = true;
1119 }
1120 }
1121 }
1122 else
1123 {
1124 if(!_randomTest)
1125 {
1126 fprintf(stdout, "Register receive codec with fixed Payload, AUDIO BACK.\n");
1127 fflush(stdout);
1128 }
1129 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1130 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
1131 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1132 myEvent->Wait(20);
1133 {
1134 WriteLockScoped wl(_apiTestRWLock);
1135 *thereIsDecoder = true;
1136 }
1137 }
1138 delete myEvent;
1139 if(!_randomTest)
1140 {
1141 fprintf(stdout, "---------------------------------------------------------\n");
1142 }
1143}
1144
1145// Playout Mode, background noise mode.
1146// Receiver Frequency, playout frequency.
1147void
1148APITest::TestPlayout(char receiveSide)
1149{
1150 AudioCodingModule* receiveACM;
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +00001151 AudioPlayoutMode* playoutMode = NULL;
1152 ACMBackgroundNoiseMode* bgnMode = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +00001153 switch(receiveSide)
1154 {
1155 case 'A':
1156 {
1157 receiveACM = _acmA;
1158 playoutMode = &_playoutModeA;
1159 bgnMode = &_bgnModeA;
1160 break;
1161 }
1162 case 'B':
1163 {
1164 receiveACM = _acmB;
1165 playoutMode = &_playoutModeB;
1166 bgnMode = &_bgnModeB;
1167 break;
1168 }
1169 default:
1170 receiveACM = _acmA;
1171 }
1172
1173 WebRtc_Word32 receiveFreqHz = receiveACM->ReceiveFrequency();
1174 WebRtc_Word32 playoutFreqHz = receiveACM->PlayoutFrequency();
1175
1176 CHECK_ERROR_MT(receiveFreqHz);
1177 CHECK_ERROR_MT(playoutFreqHz);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001178
niklase@google.com470e71d2011-07-07 08:21:25 +00001179 char bgnString[25];
1180 switch(*bgnMode)
1181 {
1182 case On:
1183 {
1184 *bgnMode = Fade;
1185 strncpy(bgnString, "Fade", 25);
1186 break;
1187 }
1188 case Fade:
1189 {
1190 *bgnMode = Off;
1191 strncpy(bgnString, "OFF", 25);
1192 break;
1193 }
1194 case Off:
1195 {
1196 *bgnMode = On;
1197 strncpy(bgnString, "ON", 25);
1198 break;
1199 }
1200 default:
1201 *bgnMode = On;
1202 strncpy(bgnString, "ON", 25);
1203 }
1204 CHECK_ERROR_MT(receiveACM->SetBackgroundNoiseMode(*bgnMode));
1205 bgnString[24] = '\0';
1206
1207 char playoutString[25];
1208 switch(*playoutMode)
1209 {
1210 case voice:
1211 {
1212 *playoutMode = fax;
1213 strncpy(playoutString, "FAX", 25);
1214 break;
1215 }
1216 case fax:
1217 {
1218 *playoutMode = streaming;
1219 strncpy(playoutString, "Streaming", 25);
1220 break;
1221 }
1222 case streaming:
1223 {
1224 *playoutMode = voice;
1225 strncpy(playoutString, "Voice", 25);
1226 break;
1227 }
1228 default:
1229 *playoutMode = voice;
1230 strncpy(playoutString, "Voice", 25);
1231 }
1232 CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
1233 playoutString[24] = '\0';
1234
1235 if(!_randomTest)
1236 {
1237 fprintf(stdout, "\n");
1238 fprintf(stdout, "In Side %c\n", receiveSide);
1239 fprintf(stdout, "---------------------------------\n");
1240 fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
1241 fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
1242 fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
1243 fprintf(stdout, "Background Noise Mode... %s\n", bgnString);
1244 }
1245}
1246
1247// set/get receiver VAD status & mode.
1248void
1249APITest::TestReceiverVAD(char side)
1250{
1251 AudioCodingModule* myACM;
tina.legrand@webrtc.org731e9ae2011-11-04 07:34:22 +00001252 int* myReceiveVADActivity;
niklase@google.com470e71d2011-07-07 08:21:25 +00001253
1254 if(side == 'A')
1255 {
1256 myACM = _acmA;
1257 myReceiveVADActivity = _receiveVADActivityA;
1258 }
1259 else
1260 {
1261 myACM = _acmB;
1262 myReceiveVADActivity = _receiveVADActivityB;
1263 }
1264
niklase@google.com470e71d2011-07-07 08:21:25 +00001265 ACMVADMode mode = myACM->ReceiveVADMode();
1266
1267 CHECK_ERROR_MT(mode);
1268
1269 if(!_randomTest)
1270 {
1271 fprintf(stdout, "\n\nCurrent Receive VAD at side %c\n", side);
1272 fprintf(stdout, "----------------------------------\n");
niklase@google.com470e71d2011-07-07 08:21:25 +00001273 fprintf(stdout, "mode.......... %d\n", (int)mode);
tina.legrand@webrtc.org731e9ae2011-11-04 07:34:22 +00001274 fprintf(stdout, "VAD Active.... %d\n", myReceiveVADActivity[0]);
1275 fprintf(stdout, "VAD Passive... %d\n", myReceiveVADActivity[1]);
1276 fprintf(stdout, "VAD Unknown... %d\n", myReceiveVADActivity[2]);
niklase@google.com470e71d2011-07-07 08:21:25 +00001277 }
1278
henrike@webrtc.org26d36672011-11-07 23:24:40 +00001279 if(!_randomTest)
niklase@google.com470e71d2011-07-07 08:21:25 +00001280 {
henrike@webrtc.org26d36672011-11-07 23:24:40 +00001281 fprintf(stdout, "\nChange Receive VAD at side %c\n\n", side);
niklase@google.com470e71d2011-07-07 08:21:25 +00001282 }
henrike@webrtc.org26d36672011-11-07 23:24:40 +00001283
1284 switch(mode)
niklase@google.com470e71d2011-07-07 08:21:25 +00001285 {
henrike@webrtc.org26d36672011-11-07 23:24:40 +00001286 case VADNormal:
1287 mode = VADAggr;
1288 break;
1289 case VADLowBitrate:
1290 mode = VADVeryAggr;
1291 break;
1292 case VADAggr:
1293 mode = VADLowBitrate;
1294 break;
1295 case VADVeryAggr:
1296 mode = VADNormal;
1297 break;
1298 default:
1299 mode = VADNormal;
1300
1301 CHECK_ERROR_MT(myACM->SetReceiveVADMode(mode));
niklase@google.com470e71d2011-07-07 08:21:25 +00001302 }
1303 for(int n = 0; n < 3; n++)
1304 {
1305 myReceiveVADActivity[n] = 0;
1306 }
1307}
1308
1309
1310void
1311APITest::TestSendVAD(char side)
1312{
1313 if(_randomTest)
1314 {
1315 return;
1316 }
1317
1318 bool* vad;
1319 bool* dtx;
1320 ACMVADMode* mode;
1321 Channel* myChannel;
1322 AudioCodingModule* myACM;
1323
1324 CodecInst myCodec;
1325 if(!_randomTest)
1326 {
1327 fprintf(stdout, "\n\n");
1328 fprintf(stdout, "-----------------------------------------------\n");
1329 fprintf(stdout, " Test VAD API\n");
1330 fprintf(stdout, "-----------------------------------------------\n");
1331 }
1332
1333 if(side == 'A')
1334 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001335 AudioCodingModule::Codec(_codecCntrA, &myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001336 vad = &_sendVADA;
1337 dtx = &_sendDTXA;
1338 mode = &_sendVADModeA;
1339 myChannel = _channel_A2B;
1340 myACM = _acmA;
1341 }
1342 else
1343 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001344 AudioCodingModule::Codec(_codecCntrB, &myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001345 vad = &_sendVADB;
1346 dtx = &_sendDTXB;
1347 mode = &_sendVADModeB;
1348 myChannel = _channel_B2A;
1349 myACM = _acmB;
1350 }
1351
1352 CheckVADStatus(side);
1353 if(!_randomTest)
1354 {
1355 fprintf(stdout, "\n\n");
1356 }
1357
1358 switch(*mode)
1359 {
1360 case VADNormal:
1361 *vad = true;
1362 *dtx = true;
1363 *mode = VADAggr;
1364 break;
1365 case VADLowBitrate:
1366 *vad = true;
1367 *dtx = true;
1368 *mode = VADVeryAggr;
1369 break;
1370 case VADAggr:
1371 *vad = true;
1372 *dtx = true;
1373 *mode = VADLowBitrate;
1374 break;
1375 case VADVeryAggr:
1376 *vad = false;
1377 *dtx = false;
1378 *mode = VADNormal;
1379 break;
1380 default:
1381 *mode = VADNormal;
1382 }
1383
1384 *dtx = (myCodec.plfreq == 32000)? false:*dtx;
1385
1386 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1387 myChannel->ResetStats();
1388
1389 CheckVADStatus(side);
1390 if(!_randomTest)
1391 {
1392 fprintf(stdout, "\n");
1393 fprintf(stdout, "-----------------------------------------------\n");
1394 }
1395
1396 // Fault Test
1397 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode)-1));
1398 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode)4));
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001399
niklase@google.com470e71d2011-07-07 08:21:25 +00001400
1401
1402}
1403
1404
1405void
1406APITest::CurrentCodec(char side)
1407{
1408 CodecInst myCodec;
niklase@google.com470e71d2011-07-07 08:21:25 +00001409 if(side == 'A')
1410 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001411 _acmA->SendCodec(&myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001412 }
1413 else
1414 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001415 _acmB->SendCodec(&myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001416 }
1417
1418 if(!_randomTest)
1419 {
1420 fprintf(stdout, "\n\n");
1421 fprintf(stdout, "Send codec in Side A\n");
1422 fprintf(stdout, "----------------------------\n");
1423 fprintf(stdout, "Name................. %s\n", myCodec.plname);
1424 fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
1425 fprintf(stdout, "Rate................. %d\n", myCodec.rate);
1426 fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
1427 fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
1428 }
1429
1430 Wait(100);
1431}
1432
1433void
1434APITest::ChangeCodec(char side)
1435{
1436 CodecInst myCodec;
1437 AudioCodingModule* myACM;
1438 WebRtc_UWord8* codecCntr;
1439 bool* thereIsEncoder;
1440 bool* vad;
1441 bool* dtx;
1442 ACMVADMode* mode;
1443 Channel* myChannel;
niklase@google.com470e71d2011-07-07 08:21:25 +00001444 // Reset and Wait
1445 if(!_randomTest)
1446 {
1447 fprintf(stdout, "Reset Encoder Side A \n");
1448 }
1449 if(side == 'A')
1450 {
1451 myACM = _acmA;
1452 codecCntr = &_codecCntrA;
1453 {
1454 WriteLockScoped wl(_apiTestRWLock);
1455 thereIsEncoder = &_thereIsEncoderA;
1456 }
1457 vad = &_sendVADA;
1458 dtx = &_sendDTXA;
1459 mode = &_sendVADModeA;
1460 myChannel = _channel_A2B;
1461 }
1462 else
1463 {
1464 myACM = _acmB;
1465 codecCntr = &_codecCntrB;
1466 {
1467 WriteLockScoped wl(_apiTestRWLock);
1468 thereIsEncoder = &_thereIsEncoderB;
1469 }
1470 vad = &_sendVADB;
1471 dtx = &_sendDTXB;
1472 mode = &_sendVADModeB;
1473 myChannel = _channel_B2A;
1474 }
1475
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001476 myACM->ResetEncoder();
niklase@google.com470e71d2011-07-07 08:21:25 +00001477 Wait(100);
1478
1479 // Register the next codec
1480 do
1481 {
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001482 *codecCntr = (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1)?
1483 (*codecCntr + 1):0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001484
1485 if(*codecCntr == 0)
1486 {
1487 //printf("Initialize Sender Side A \n");
1488 {
1489 WriteLockScoped wl(_apiTestRWLock);
1490 *thereIsEncoder = false;
1491 }
1492 CHECK_ERROR_MT(myACM->InitializeSender());
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001493 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +00001494
1495 // After Initialization CN is lost, re-register them
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001496 if(AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0)
niklase@google.com470e71d2011-07-07 08:21:25 +00001497 {
1498 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1499 }
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001500 if(AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0)
niklase@google.com470e71d2011-07-07 08:21:25 +00001501 {
1502 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1503 }
1504 // VAD & DTX are disabled after initialization
1505 *vad = false;
1506 *dtx = false;
1507 _writeToFile = false;
1508 }
1509
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001510 AudioCodingModule::Codec(*codecCntr, &myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001511 } while(!STR_CASE_CMP(myCodec.plname, "CN") ||
1512 !STR_CASE_CMP(myCodec.plname, "telephone-event") ||
1513 !STR_CASE_CMP(myCodec.plname, "RED"));
1514
1515 if(!_randomTest)
1516 {
1517 fprintf(stdout, "\n====================================================================\n");
1518 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1519 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1520 }
1521 //std::cout<< std::flush;
1522
1523 // NO DTX for supe-wideband codec at this point
1524 if(myCodec.plfreq == 32000)
1525 {
1526 *dtx = false;
1527 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1528
1529 }
1530
1531 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1532 myChannel->ResetStats();
1533 {
1534 WriteLockScoped wl(_apiTestRWLock);
1535 *thereIsEncoder = true;
1536 }
1537 Wait(500);
1538}
1539
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001540
1541void
niklase@google.com470e71d2011-07-07 08:21:25 +00001542APITest::LookForDTMF(char side)
1543{
1544 if(!_randomTest)
1545 {
1546 fprintf(stdout, "\n\nLooking for DTMF Signal in Side %c\n", side);
1547 fprintf(stdout, "----------------------------------------\n");
1548 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001549
niklase@google.com470e71d2011-07-07 08:21:25 +00001550 if(side == 'A')
1551 {
1552 _acmB->RegisterIncomingMessagesCallback(NULL);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001553 _acmA->RegisterIncomingMessagesCallback(_dtmfCallback);
niklase@google.com470e71d2011-07-07 08:21:25 +00001554 Wait(1000);
1555 _acmA->RegisterIncomingMessagesCallback(NULL);
1556 }
1557 else
1558 {
1559 _acmA->RegisterIncomingMessagesCallback(NULL);
1560 _acmB->RegisterIncomingMessagesCallback(_dtmfCallback);
1561 Wait(1000);
1562 _acmB->RegisterIncomingMessagesCallback(NULL);
1563 }
1564}
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +00001565
1566} // namespace webrtc
1567