blob: 6e4115d305d322d68897cb82379e7d620c524a4f [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
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000013#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000016
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +000017#include <cctype>
18#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"
23#include "webrtc/common_types.h"
24#include "webrtc/engine_configurations.h"
25#include "webrtc/modules/audio_coding/main/source/acm_common_defs.h"
26#include "webrtc/modules/audio_coding/main/test/utility.h"
27#include "webrtc/system_wrappers/interface/event_wrapper.h"
28#include "webrtc/system_wrappers/interface/thread_wrapper.h"
29#include "webrtc/system_wrappers/interface/tick_util.h"
30#include "webrtc/system_wrappers/interface/trace.h"
31#include "webrtc/test/testsupport/fileutils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000032
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000033namespace webrtc {
34
niklase@google.com470e71d2011-07-07 08:21:25 +000035#define TEST_DURATION_SEC 600
36
37#define NUMBER_OF_SENDER_TESTS 6
38
39#define MAX_FILE_NAME_LENGTH_BYTE 500
kjellander@webrtc.org5490c712011-12-21 13:34:18 +000040#define CHECK_THREAD_NULLITY(myThread, S) \
41 if(myThread != NULL) \
42 { \
43 unsigned int i; \
44 (myThread)->Start(i); \
45 } \
46 else \
47 { \
48 ADD_FAILURE() << S; \
49 }
niklase@google.com470e71d2011-07-07 08:21:25 +000050
niklase@google.com470e71d2011-07-07 08:21:25 +000051
52void
pbos@webrtc.org0946a562013-04-09 00:28:06 +000053APITest::Wait(uint32_t waitLengthMs)
niklase@google.com470e71d2011-07-07 08:21:25 +000054{
55 if(_randomTest)
56 {
57 return;
58 }
59 else
60 {
61 EventWrapper* myEvent = EventWrapper::Create();
62 myEvent->Wait(waitLengthMs);
63 delete myEvent;
64 return;
65 }
66}
67
68
69
70APITest::APITest():
71_acmA(NULL),
72_acmB(NULL),
73_channel_A2B(NULL),
74_channel_B2A(NULL),
75_writeToFile(true),
76_pullEventA(NULL),
77_pushEventA(NULL),
78_processEventA(NULL),
79_apiEventA(NULL),
80_pullEventB(NULL),
81_pushEventB(NULL),
82_processEventB(NULL),
83_apiEventB(NULL),
84_codecCntrA(0),
85_codecCntrB(0),
niklase@google.com470e71d2011-07-07 08:21:25 +000086_thereIsEncoderA(false),
87_thereIsEncoderB(false),
88_thereIsDecoderA(false),
89_thereIsDecoderB(false),
90_sendVADA(false),
91_sendDTXA(false),
92_sendVADModeA(VADNormal),
93_sendVADB(false),
94_sendDTXB(false),
95_sendVADModeB(VADNormal),
96_minDelayA(0),
97_minDelayB(0),
98_dotPositionA(0),
99_dotMoveDirectionA(1),
100_dotPositionB(39),
101_dotMoveDirectionB(-1),
102_dtmfCallback(NULL),
103_vadCallbackA(NULL),
104_vadCallbackB(NULL),
105_apiTestRWLock(*RWLockWrapper::CreateRWLock()),
106_randomTest(false),
107_testNumA(0),
108_testNumB(1)
109{
110 int n;
111 for( n = 0; n < 32; n++)
112 {
113 _payloadUsed[n] = false;
114 }
115
116 for(n = 0; n < 3; n++)
117 {
118 _receiveVADActivityA[n] = 0;
119 _receiveVADActivityB[n] = 0;
120 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000121
niklase@google.com470e71d2011-07-07 08:21:25 +0000122 _movingDot[40] = '\0';
123
124 for(int n = 0; n <40; n++)
125 {
126 _movingDot[n] = ' ';
127 }
128}
129
130APITest::~APITest()
131{
132 DESTROY_ACM(_acmA);
133 DESTROY_ACM(_acmB);
134
135 DELETE_POINTER(_channel_A2B);
136 DELETE_POINTER(_channel_B2A);
137
138 DELETE_POINTER(_pushEventA);
139 DELETE_POINTER(_pullEventA);
140 DELETE_POINTER(_processEventA);
141 DELETE_POINTER(_apiEventA);
142
143 DELETE_POINTER(_pushEventB);
144 DELETE_POINTER(_pullEventB);
145 DELETE_POINTER(_processEventB);
146 DELETE_POINTER(_apiEventB);
147
148 _inFileA.Close();
149 _outFileA.Close();
150
151 _inFileB.Close();
152 _outFileB.Close();
153
154 DELETE_POINTER(_dtmfCallback);
155 DELETE_POINTER(_vadCallbackA);
156 DELETE_POINTER(_vadCallbackB);
157
158 delete &_apiTestRWLock;
159}
160
161
162
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000163//int16_t
164//APITest::SetInFile(char* fileName, uint16_t frequencyHz)
niklase@google.com470e71d2011-07-07 08:21:25 +0000165//{
166// return _inFile.Open(fileName, frequencyHz, "rb");
167//}
168//
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000169//int16_t
170//APITest::SetOutFile(char* fileName, uint16_t frequencyHz)
niklase@google.com470e71d2011-07-07 08:21:25 +0000171//{
172// return _outFile.Open(fileName, frequencyHz, "wb");
173//}
174
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000175int16_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000176APITest::SetUp()
177{
178 _acmA = AudioCodingModule::Create(1);
179 _acmB = AudioCodingModule::Create(2);
180
181 CodecInst dummyCodec;
182 int lastPayloadType = 0;
183
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000184 int16_t numCodecs = _acmA->NumberOfCodecs();
185 for(uint8_t n = 0; n < numCodecs; n++)
niklase@google.com470e71d2011-07-07 08:21:25 +0000186 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000187 AudioCodingModule::Codec(n, &dummyCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000188 if((STR_CASE_CMP(dummyCodec.plname, "CN") == 0) &&
189 (dummyCodec.plfreq == 32000))
190 {
191 continue;
192 }
193
194 printf("Register Receive Codec %s ", dummyCodec.plname);
195
196 if((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname))
197 {
198 // Check registration with an already occupied payload type
199 int currentPayloadType = dummyCodec.pltype;
200 dummyCodec.pltype = 97; //lastPayloadType;
201 CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
202 dummyCodec.pltype = currentPayloadType;
203 }
204
205 if((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname))
206 {
207 // test if re-registration works;
208 CodecInst nextCodec;
209 int currentPayloadType = dummyCodec.pltype;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000210 AudioCodingModule::Codec(n + 1, &nextCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000211 dummyCodec.pltype = nextCodec.pltype;
212 if(!FixedPayloadTypeCodec(nextCodec.plname))
213 {
214 _acmB->RegisterReceiveCodec(dummyCodec);
215 }
216 dummyCodec.pltype = currentPayloadType;
217 }
218
219 if((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname))
220 {
221 // test if un-registration works;
222 CodecInst nextCodec;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000223 AudioCodingModule::Codec(n + 1, &nextCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000224 nextCodec.pltype = dummyCodec.pltype;
225 if(!FixedPayloadTypeCodec(nextCodec.plname))
226 {
227 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
228 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
229 }
230 }
231
232
233 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
234 printf(" side A done!");
235 CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
236 printf(" side B done!\n");
237
238 if(!strcmp(dummyCodec.plname, "CN"))
239 {
240 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
241 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
242 }
243 lastPayloadType = dummyCodec.pltype;
244 if((lastPayloadType >= 96) && (lastPayloadType <= 127))
245 {
246 _payloadUsed[lastPayloadType - 96] = true;
247 }
248 }
249 _thereIsDecoderA = true;
250 _thereIsDecoderB = true;
251
252 // Register Send Codec
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000253 AudioCodingModule::Codec((uint8_t)_codecCntrA, &dummyCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000254 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
255 _thereIsEncoderA = true;
256 //
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000257 AudioCodingModule::Codec((uint8_t)_codecCntrB, &dummyCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000258 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
259 _thereIsEncoderB = true;
260
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000261 uint16_t frequencyHz;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000262
niklase@google.com470e71d2011-07-07 08:21:25 +0000263 printf("\n\nAPI Test\n");
264 printf("========\n");
265 printf("Hit enter to accept the default values indicated in []\n\n");
266
267 //--- Input A
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000268 std::string file_name =
269 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
niklase@google.com470e71d2011-07-07 08:21:25 +0000270 frequencyHz = 32000;
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000271 printf("Enter input file at side A [%s]: ", file_name.c_str());
272 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
273 _inFileA.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000274
275 //--- Output A
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000276 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
277 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
278 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
279 _outFileA.Open(out_file_a, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000280
281 //--- Input B
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000282 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
283 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
284 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
285 _inFileB.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000286
287 //--- Output B
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000288 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
289 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
290 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
291 _outFileB.Open(out_file_b, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000292
293 //--- Set A-to-B channel
294 _channel_A2B = new Channel(2);
295 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
296 _channel_A2B->RegisterReceiverACM(_acmB);
297
298 //--- Set B-to-A channel
299 _channel_B2A = new Channel(1);
300 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
301 _channel_B2A->RegisterReceiverACM(_acmA);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000302
niklase@google.com470e71d2011-07-07 08:21:25 +0000303 //--- EVENT TIMERS
304 // A
305 _pullEventA = EventWrapper::Create();
306 _pushEventA = EventWrapper::Create();
307 _processEventA = EventWrapper::Create();
308 _apiEventA = EventWrapper::Create();
309 // B
310 _pullEventB = EventWrapper::Create();
311 _pushEventB = EventWrapper::Create();
312 _processEventB = EventWrapper::Create();
313 _apiEventB = EventWrapper::Create();
314
315 //--- I/O params
316 // A
317 _outFreqHzA = _outFileA.SamplingFrequency();
318 // B
319 _outFreqHzB = _outFileB.SamplingFrequency();
320
321
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000322 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
niklase@google.com470e71d2011-07-07 08:21:25 +0000323
324 char print[11];
325
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +0000326 // Create a trace file.
327 Trace::CreateTrace();
328 Trace::SetTraceFile((webrtc::test::OutputPath() +
329 "acm_api_trace.txt").c_str());
330
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 printf("\nRandom Test (y/n)?");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000332 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 print[10] = '\0';
334 if(strstr(print, "y") != NULL)
335 {
336 _randomTest = true;
337 _verbose = false;
338 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 }
340 else
341 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 _randomTest = false;
343 printf("\nPrint Tests (y/n)? ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000344 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000345 print[10] = '\0';
346 if(strstr(print, "y") == NULL)
347 {
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000348 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000349 _verbose = false;
350 }
351 }
352
353#ifdef WEBRTC_DTMF_DETECTION
354 _dtmfCallback = new DTMFDetector;
355#endif
356 _vadCallbackA = new VADCallback;
357 _vadCallbackB = new VADCallback;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000358
niklase@google.com470e71d2011-07-07 08:21:25 +0000359 return 0;
360}
361
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000362bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000363APITest::PushAudioThreadA(void* obj)
364{
365 return static_cast<APITest*>(obj)->PushAudioRunA();
366}
367
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000368bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000369APITest::PushAudioThreadB(void* obj)
370{
371 return static_cast<APITest*>(obj)->PushAudioRunB();
372}
373
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000374bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000375APITest::PullAudioThreadA(void* obj)
376{
377 return static_cast<APITest*>(obj)->PullAudioRunA();
378}
379
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000380bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000381APITest::PullAudioThreadB(void* obj)
382{
383 return static_cast<APITest*>(obj)->PullAudioRunB();
384}
385
386bool
387APITest::ProcessThreadA(void* obj)
388{
389 return static_cast<APITest*>(obj)->ProcessRunA();
390}
391
392bool
393APITest::ProcessThreadB(void* obj)
394{
395 return static_cast<APITest*>(obj)->ProcessRunB();
396}
397
398bool
399APITest::APIThreadA(void* obj)
400{
401 return static_cast<APITest*>(obj)->APIRunA();
402}
403
404bool
405APITest::APIThreadB(void* obj)
406{
407 return static_cast<APITest*>(obj)->APIRunB();
408}
409
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000410bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000411APITest::PullAudioRunA()
412{
413 _pullEventA->Wait(100);
414 AudioFrame audioFrame;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000415 if(_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame) < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000416 {
417 bool thereIsDecoder;
418 {
419 ReadLockScoped rl(_apiTestRWLock);
420 thereIsDecoder = _thereIsDecoderA;
421 }
422 if(thereIsDecoder)
423 {
424 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
425 }
426 }
427 else
428 {
429 if(_writeToFile)
430 {
431 _outFileA.Write10MsData(audioFrame);
432 }
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000433 _receiveVADActivityA[(int)audioFrame.vad_activity_]++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000434 }
435 return true;
436}
437
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000438bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000439APITest::PullAudioRunB()
440{
441 _pullEventB->Wait(100);
442 AudioFrame audioFrame;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000443 if(_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame) < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000444 {
445 bool thereIsDecoder;
446 {
447 ReadLockScoped rl(_apiTestRWLock);
448 thereIsDecoder = _thereIsDecoderB;
449 }
450 if(thereIsDecoder)
451 {
452 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
453 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
454 }
455 }
456 else
457 {
458 if(_writeToFile)
459 {
460 _outFileB.Write10MsData(audioFrame);
461 }
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000462 _receiveVADActivityB[(int)audioFrame.vad_activity_]++;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000463 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000464 return true;
465}
466
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000467bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000468APITest::PushAudioRunA()
469{
470 _pushEventA->Wait(100);
471 AudioFrame audioFrame;
472 _inFileA.Read10MsData(audioFrame);
473 if(_acmA->Add10MsData(audioFrame) < 0)
474 {
475 bool thereIsEncoder;
476 {
477 ReadLockScoped rl(_apiTestRWLock);
478 thereIsEncoder = _thereIsEncoderA;
479 }
480 if(thereIsEncoder)
481 {
482 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
483 }
484 }
485 return true;
486}
487
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000488bool
niklase@google.com470e71d2011-07-07 08:21:25 +0000489APITest::PushAudioRunB()
490{
491 _pushEventB->Wait(100);
492 AudioFrame audioFrame;
493 _inFileB.Read10MsData(audioFrame);
494 if(_acmB->Add10MsData(audioFrame) < 0)
495 {
496 bool thereIsEncoder;
497 {
498 ReadLockScoped rl(_apiTestRWLock);
499 thereIsEncoder = _thereIsEncoderB;
500 }
501
502 if(thereIsEncoder)
503 {
504 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
505 }
506 }
507
508 return true;
509}
510
511bool
512APITest::ProcessRunA()
513{
514 _processEventA->Wait(100);
515 if(_acmA->Process() < 0)
516 {
517 // do not print error message if there is no encoder
518 bool thereIsEncoder;
519 {
520 ReadLockScoped rl(_apiTestRWLock);
521 thereIsEncoder = _thereIsEncoderA;
522 }
523
524 if(thereIsEncoder)
525 {
526 fprintf(stderr, "\n>>>>> Process Failed at A <<<<<\n");
527 }
528 }
529 return true;
530}
531
532bool
533APITest::ProcessRunB()
534{
535 _processEventB->Wait(100);
536 if(_acmB->Process() < 0)
537 {
538 bool thereIsEncoder;
539 {
540 ReadLockScoped rl(_apiTestRWLock);
541 thereIsEncoder = _thereIsEncoderB;
542 }
543 if(thereIsEncoder)
544 {
545 fprintf(stderr, "\n>>>>> Process Failed at B <<<<<\n");
546 }
547 }
548 return true;
549}
550
551/*/
552 *
553 * In side A we test the APIs which are related to sender Side.
554 *
555/*/
556
557
558void
559APITest::RunTest(char thread)
560{
561 int testNum;
562 {
563 WriteLockScoped cs(_apiTestRWLock);
564 if(thread == 'A')
565 {
566 _testNumA = (_testNumB + 1 + (rand() % 6)) % 7;
567 testNum = _testNumA;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000568
niklase@google.com470e71d2011-07-07 08:21:25 +0000569 _movingDot[_dotPositionA] = ' ';
570 if(_dotPositionA == 0)
571 {
572 _dotMoveDirectionA = 1;
573 }
574 if(_dotPositionA == 19)
575 {
576 _dotMoveDirectionA = -1;
577 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000578 _dotPositionA += _dotMoveDirectionA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000579 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0)? '>':'<';
580 }
581 else
582 {
583 _testNumB = (_testNumA + 1 + (rand() % 6)) % 7;
584 testNum = _testNumB;
585
586 _movingDot[_dotPositionB] = ' ';
587 if(_dotPositionB == 20)
588 {
589 _dotMoveDirectionB = 1;
590 }
591 if(_dotPositionB == 39)
592 {
593 _dotMoveDirectionB = -1;
594 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000595 _dotPositionB += _dotMoveDirectionB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000596 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0)? '>':'<';
597 }
598 //fprintf(stderr, "%c: %d \n", thread, testNum);
599 //fflush(stderr);
600 }
601 switch(testNum)
602 {
603 case 0:
604 CurrentCodec('A');
605 ChangeCodec('A');
606 break;
607 case 1:
608 TestPlayout('B');
609 break;
610 case 2:
611 if(!_randomTest)
612 {
613 fprintf(stdout, "\nTesting Delay ...\n");
614 }
615 TestDelay('A');
616 break;
617 case 3:
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000618 TestSendVAD('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000619 break;
620 case 4:
621 TestRegisteration('A');
622 break;
623 case 5:
624 TestReceiverVAD('A');
625 break;
626 case 6:
627#ifdef WEBRTC_DTMF_DETECTION
628 LookForDTMF('A');
629#endif
630 break;
631 default:
632 fprintf(stderr, "Wrong Test Number\n");
633 getchar();
634 exit(1);
635 }
636}
637
638
639
640bool
641APITest::APIRunA()
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000642{
niklase@google.com470e71d2011-07-07 08:21:25 +0000643 _apiEventA->Wait(50);
644
645 bool randomTest;
646 {
647 ReadLockScoped rl(_apiTestRWLock);
648 randomTest = _randomTest;
649 }
650 if(randomTest)
651 {
652 RunTest('A');
653 }
654 else
655 {
656 CurrentCodec('A');
657 ChangeCodec('A');
658 TestPlayout('B');
659 if(_codecCntrA == 0)
660 {
661 fprintf(stdout, "\nTesting Delay ...\n");
662 TestDelay('A');
663 }
664 // VAD TEST
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000665 TestSendVAD('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000666 TestRegisteration('A');
667 TestReceiverVAD('A');
668#ifdef WEBRTC_DTMF_DETECTION
669 LookForDTMF('A');
670#endif
671 }
672 return true;
673}
674
675bool
676APITest::APIRunB()
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000677{
niklase@google.com470e71d2011-07-07 08:21:25 +0000678 _apiEventB->Wait(50);
679 bool randomTest;
680 {
681 ReadLockScoped rl(_apiTestRWLock);
682 randomTest = _randomTest;
683 }
684 //_apiEventB->Wait(2000);
685 if(randomTest)
686 {
687 RunTest('B');
688 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000689
niklase@google.com470e71d2011-07-07 08:21:25 +0000690 return true;
691}
692
693void
694APITest::Perform()
695{
696 SetUp();
697
698 //--- THREADS
699 // A
700 // PUSH
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000701 ThreadWrapper* myPushAudioThreadA = ThreadWrapper::CreateThread(PushAudioThreadA,
niklase@google.com470e71d2011-07-07 08:21:25 +0000702 this, kNormalPriority, "PushAudioThreadA");
703 CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
704 // PULL
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000705 ThreadWrapper* myPullAudioThreadA = ThreadWrapper::CreateThread(PullAudioThreadA,
niklase@google.com470e71d2011-07-07 08:21:25 +0000706 this, kNormalPriority, "PullAudioThreadA");
707 CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
708 // Process
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000709 ThreadWrapper* myProcessThreadA = ThreadWrapper::CreateThread(ProcessThreadA,
niklase@google.com470e71d2011-07-07 08:21:25 +0000710 this, kNormalPriority, "ProcessThreadA");
711 CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000712 // API
713 ThreadWrapper* myAPIThreadA = ThreadWrapper::CreateThread(APIThreadA,
niklase@google.com470e71d2011-07-07 08:21:25 +0000714 this, kNormalPriority, "APIThreadA");
715 CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
716 // B
717 // PUSH
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000718 ThreadWrapper* myPushAudioThreadB = ThreadWrapper::CreateThread(PushAudioThreadB,
niklase@google.com470e71d2011-07-07 08:21:25 +0000719 this, kNormalPriority, "PushAudioThreadB");
720 CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
721 // PULL
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000722 ThreadWrapper* myPullAudioThreadB = ThreadWrapper::CreateThread(PullAudioThreadB,
niklase@google.com470e71d2011-07-07 08:21:25 +0000723 this, kNormalPriority, "PullAudioThreadB");
724 CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
725 // Process
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000726 ThreadWrapper* myProcessThreadB = ThreadWrapper::CreateThread(ProcessThreadB,
niklase@google.com470e71d2011-07-07 08:21:25 +0000727 this, kNormalPriority, "ProcessThreadB");
728 CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
729 // API
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000730 ThreadWrapper* myAPIThreadB = ThreadWrapper::CreateThread(APIThreadB,
niklase@google.com470e71d2011-07-07 08:21:25 +0000731 this, kNormalPriority, "APIThreadB");
732 CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000733
niklase@google.com470e71d2011-07-07 08:21:25 +0000734
735 //_apiEventA->StartTimer(true, 5000);
736 //_apiEventB->StartTimer(true, 5000);
737
738 _processEventA->StartTimer(true, 10);
739 _processEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000740
niklase@google.com470e71d2011-07-07 08:21:25 +0000741 _pullEventA->StartTimer(true, 10);
742 _pullEventB->StartTimer(true, 10);
743
744 _pushEventA->StartTimer(true, 10);
745 _pushEventB->StartTimer(true, 10);
746
747 // Keep main thread waiting for sender/receiver
748 // threads to complete
749 EventWrapper* completeEvent = EventWrapper::Create();
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000750 uint64_t startTime = TickTime::MillisecondTimestamp();
751 uint64_t currentTime;
niklase@google.com470e71d2011-07-07 08:21:25 +0000752 do
753 {
754 {
755 //ReadLockScoped rl(_apiTestRWLock);
756 //fprintf(stderr, "\r%s", _movingDot);
757 }
758 //fflush(stderr);
759 completeEvent->Wait(50);
760 currentTime = TickTime::MillisecondTimestamp();
761 } while((currentTime - startTime) < 120000); // Run test in 2 minutes (120000 ms)
762
763 //completeEvent->Wait(0xFFFFFFFF);//(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
764 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000765
niklase@google.com470e71d2011-07-07 08:21:25 +0000766 myPushAudioThreadA->Stop();
767 myPullAudioThreadA->Stop();
768 myProcessThreadA->Stop();
769 myAPIThreadA->Stop();
770
771 delete myPushAudioThreadA;
772 delete myPullAudioThreadA;
773 delete myProcessThreadA;
774 delete myAPIThreadA;
775
776
777 myPushAudioThreadB->Stop();
778 myPullAudioThreadB->Stop();
779 myProcessThreadB->Stop();
780 myAPIThreadB->Stop();
781
782 delete myPushAudioThreadB;
783 delete myPullAudioThreadB;
784 delete myProcessThreadB;
785 delete myAPIThreadB;
786}
787
788
789void
790APITest::CheckVADStatus(char side)
791{
792
793 bool dtxEnabled;
794 bool vadEnabled;
795 ACMVADMode vadMode;
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000796
niklase@google.com470e71d2011-07-07 08:21:25 +0000797 if(side == 'A')
798 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000799 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000800 _acmA->RegisterVADCallback(NULL);
801 _vadCallbackA->Reset();
802 _acmA->RegisterVADCallback(_vadCallbackA);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000803
niklase@google.com470e71d2011-07-07 08:21:25 +0000804 if(!_randomTest)
805 {
806 if(_verbose)
807 {
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000808 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d",
niklase@google.com470e71d2011-07-07 08:21:25 +0000809 dtxEnabled? "ON":"OFF",
810 vadEnabled? "ON":"OFF",
811 (int)vadMode);
812 Wait(5000);
813 fprintf(stdout, " => bit-rate %3.0f kbps\n",
814 _channel_A2B->BitRate());
815 }
816 else
817 {
818 Wait(5000);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000819 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
niklase@google.com470e71d2011-07-07 08:21:25 +0000820 dtxEnabled? "ON":"OFF",
821 vadEnabled? "ON":"OFF",
822 (int)vadMode,
823 _channel_A2B->BitRate());
824 }
825 _vadCallbackA->PrintFrameTypes();
826 }
827
828 if(dtxEnabled != _sendDTXA)
829 {
830 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
831 }
832 if((vadEnabled != _sendVADA) && (!dtxEnabled))
833 {
834 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
835 }
836 if((vadMode != _sendVADModeA) && vadEnabled)
837 {
838 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
839 }
840 }
841 else
842 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000843 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000844
845 _acmB->RegisterVADCallback(NULL);
846 _vadCallbackB->Reset();
847 _acmB->RegisterVADCallback(_vadCallbackB);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000848
niklase@google.com470e71d2011-07-07 08:21:25 +0000849 if(!_randomTest)
850 {
851 if(_verbose)
852 {
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000853 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d",
niklase@google.com470e71d2011-07-07 08:21:25 +0000854 dtxEnabled? "ON":"OFF",
855 vadEnabled? "ON":"OFF",
856 (int)vadMode);
857 Wait(5000);
858 fprintf(stdout, " => bit-rate %3.0f kbps\n",
859 _channel_B2A->BitRate());
860 }
861 else
862 {
863 Wait(5000);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000864 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
niklase@google.com470e71d2011-07-07 08:21:25 +0000865 dtxEnabled? "ON":"OFF",
866 vadEnabled? "ON":"OFF",
867 (int)vadMode,
868 _channel_B2A->BitRate());
869 }
870 _vadCallbackB->PrintFrameTypes();
871 }
872
873 if(dtxEnabled != _sendDTXB)
874 {
875 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
876 }
877 if((vadEnabled != _sendVADB) && (!dtxEnabled))
878 {
879 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
880 }
881 if((vadMode != _sendVADModeB) && vadEnabled)
882 {
883 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
884 }
885 }
886}
887
888// Set Min delay, get delay, playout timestamp
889void
890APITest::TestDelay(char side)
891{
892 AudioCodingModule* myACM;
893 Channel* myChannel;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000894 int32_t* myMinDelay;
niklase@google.com470e71d2011-07-07 08:21:25 +0000895 EventWrapper* myEvent = EventWrapper::Create();
896
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000897 uint32_t inTimestamp = 0;
898 uint32_t outTimestamp = 0;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000899 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000900
901 double averageEstimDelay = 0;
902 double averageDelay = 0;
903
904 CircularBuffer estimDelayCB(100);
niklase@google.com470e71d2011-07-07 08:21:25 +0000905 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000906
907 if(side == 'A')
908 {
909 myACM = _acmA;
910 myChannel = _channel_B2A;
911 myMinDelay = &_minDelayA;
912 }
913 else
914 {
915 myACM = _acmB;
916 myChannel = _channel_A2B;
917 myMinDelay = &_minDelayB;
918 }
919
920
921 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
922
923
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000924 inTimestamp = myChannel->LastInTimestamp();
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000925 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
niklase@google.com470e71d2011-07-07 08:21:25 +0000926
927 if(!_randomTest)
928 {
929 myEvent->StartTimer(true, 30);
930 int n = 0;
931 int settlePoint = 5000;
932 while(n < settlePoint + 400)
933 {
934 myEvent->Wait(1000);
935
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000936 inTimestamp = myChannel->LastInTimestamp();
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000937 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
niklase@google.com470e71d2011-07-07 08:21:25 +0000938
939 //std::cout << outTimestamp << std::endl << std::flush;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000940 estimDelay = (double)((uint32_t)(inTimestamp - outTimestamp)) /
niklase@google.com470e71d2011-07-07 08:21:25 +0000941 ((double)myACM->ReceiveFrequency() / 1000.0);
942
943 estimDelayCB.Update(estimDelay);
944
945 estimDelayCB.ArithMean(averageEstimDelay);
946 //printf("\n %6.1f \n", estimDelay);
947 //std::cout << " " << std::flush;
948
niklase@google.com470e71d2011-07-07 08:21:25 +0000949 if(_verbose)
950 {
951 fprintf(stdout, "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
952 *myMinDelay, averageDelay, averageEstimDelay);
953 std::cout << " " << std::flush;
954 }
955 if((averageDelay > *myMinDelay) && (n < settlePoint))
956 {
957 settlePoint = n;
958 }
959 n++;
960 }
961 myEvent->StopTimer();
962 }
963
964 if((!_verbose) && (!_randomTest))
965 {
966 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
967 *myMinDelay, averageDelay, averageEstimDelay);
968 }
969
970 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000971
niklase@google.com470e71d2011-07-07 08:21:25 +0000972 ACMNetworkStatistics networkStat;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000973 CHECK_ERROR_MT(myACM->NetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000974
975 if(!_randomTest)
976 {
977 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
978 fprintf(stdout, "--------------------------------------\n");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000979 fprintf(stdout, "buffer-size............. %d\n", networkStat.currentBufferSize);
henrik.lundin@webrtc.orgd4398702012-01-04 13:09:55 +0000980 fprintf(stdout, "Preferred buffer-size... %d\n", networkStat.preferredBufferSize);
981 fprintf(stdout, "Peaky jitter mode........%d\n", networkStat.jitterPeaksFound);
niklase@google.com470e71d2011-07-07 08:21:25 +0000982 fprintf(stdout, "packet-size rate........ %d\n", networkStat.currentPacketLossRate);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000983 fprintf(stdout, "discard rate............ %d\n", networkStat.currentDiscardRate);
984 fprintf(stdout, "expand rate............. %d\n", networkStat.currentExpandRate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000985 fprintf(stdout, "Preemptive rate......... %d\n", networkStat.currentPreemptiveRate);
986 fprintf(stdout, "Accelerate rate......... %d\n", networkStat.currentAccelerateRate);
henrik.lundin@webrtc.orgd4398702012-01-04 13:09:55 +0000987 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
988 fprintf(stdout, "Mean waiting time....... %d\n", networkStat.meanWaitingTimeMs);
989 fprintf(stdout, "Median waiting time..... %d\n", networkStat.medianWaitingTimeMs);
henrik.lundin@webrtc.org053c7992012-01-12 14:16:44 +0000990 fprintf(stdout, "Min waiting time........ %d\n", networkStat.minWaitingTimeMs);
henrik.lundin@webrtc.orgd4398702012-01-04 13:09:55 +0000991 fprintf(stdout, "Max waiting time........ %d\n", networkStat.maxWaitingTimeMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000992 }
993
994 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
995
996 if(!_randomTest)
997 {
998 myEvent->Wait(500);
999 fprintf(stdout, "\n");
1000 fprintf(stdout, "\n");
1001 }
1002 delete myEvent;
1003}
1004
1005// Unregister a codec & register again.
1006void
1007APITest::TestRegisteration(char sendSide)
1008{
1009 AudioCodingModule* sendACM;
1010 AudioCodingModule* receiveACM;
1011 bool* thereIsDecoder;
1012 EventWrapper* myEvent = EventWrapper::Create();
1013
1014 if(!_randomTest)
1015 {
1016 fprintf(stdout, "\n\n");
1017 fprintf(stdout, "---------------------------------------------------------\n");
1018 fprintf(stdout, " Unregister/register Receive Codec\n");
1019 fprintf(stdout, "---------------------------------------------------------\n");
1020 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001021
niklase@google.com470e71d2011-07-07 08:21:25 +00001022 switch(sendSide)
1023 {
1024 case 'A':
1025 {
1026 sendACM = _acmA;
1027 receiveACM = _acmB;
1028 thereIsDecoder = &_thereIsDecoderB;
1029 break;
1030 }
1031 case 'B':
1032 {
1033 sendACM = _acmB;
1034 receiveACM = _acmA;
1035 thereIsDecoder = &_thereIsDecoderA;
1036 break;
1037 }
1038 default:
1039 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n", sendSide);
1040 exit(-1);
1041 }
1042
1043 CodecInst myCodec;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001044 if(sendACM->SendCodec(&myCodec) < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +00001045 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001046 AudioCodingModule::Codec(_codecCntrA, &myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001047 }
1048
1049 if(!_randomTest)
1050 {
1051 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
1052 fflush(stdout);
1053 }
1054 {
1055 WriteLockScoped wl(_apiTestRWLock);
1056 *thereIsDecoder = false;
1057 }
1058 //myEvent->Wait(20);
1059 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
1060 Wait(1000);
1061
1062 int currentPayload = myCodec.pltype;
1063
1064 if(!FixedPayloadTypeCodec(myCodec.plname))
1065 {
pbos@webrtc.org0946a562013-04-09 00:28:06 +00001066 int32_t i;
niklase@google.com470e71d2011-07-07 08:21:25 +00001067 for(i = 0; i < 32; i++)
1068 {
1069 if(!_payloadUsed[i])
1070 {
1071 if(!_randomTest)
1072 {
1073 fprintf(stdout, "Register receive codec with new Payload, AUDIO BACK.\n");
1074 }
1075 //myCodec.pltype = i + 96;
1076 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1077 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
1078 //myEvent->Wait(20);
1079 //{
1080 // WriteLockScoped wl(_apiTestRWLock);
1081 // *thereIsDecoder = true;
1082 //}
1083 Wait(1000);
1084
1085 if(!_randomTest)
1086 {
1087 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
1088 }
1089 //{
1090 // WriteLockScoped wl(_apiTestRWLock);
1091 // *thereIsDecoder = false;
1092 //}
1093 //myEvent->Wait(20);
1094 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
1095 Wait(1000);
1096
1097 myCodec.pltype = currentPayload;
1098 if(!_randomTest)
1099 {
1100 fprintf(stdout, "Register receive codec with default Payload, AUDIO BACK.\n");
1101 fflush(stdout);
1102 }
1103 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1104 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
1105 myEvent->Wait(20);
1106 {
1107 WriteLockScoped wl(_apiTestRWLock);
1108 *thereIsDecoder = true;
1109 }
1110 Wait(1000);
1111
1112 break;
1113 }
1114 }
1115 if(i == 32)
1116 {
1117 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1118 {
1119 WriteLockScoped wl(_apiTestRWLock);
1120 *thereIsDecoder = true;
1121 }
1122 }
1123 }
1124 else
1125 {
1126 if(!_randomTest)
1127 {
1128 fprintf(stdout, "Register receive codec with fixed Payload, AUDIO BACK.\n");
1129 fflush(stdout);
1130 }
1131 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1132 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
1133 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
1134 myEvent->Wait(20);
1135 {
1136 WriteLockScoped wl(_apiTestRWLock);
1137 *thereIsDecoder = true;
1138 }
1139 }
1140 delete myEvent;
1141 if(!_randomTest)
1142 {
1143 fprintf(stdout, "---------------------------------------------------------\n");
1144 }
1145}
1146
1147// Playout Mode, background noise mode.
1148// Receiver Frequency, playout frequency.
1149void
1150APITest::TestPlayout(char receiveSide)
1151{
1152 AudioCodingModule* receiveACM;
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +00001153 AudioPlayoutMode* playoutMode = NULL;
1154 ACMBackgroundNoiseMode* bgnMode = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +00001155 switch(receiveSide)
1156 {
1157 case 'A':
1158 {
1159 receiveACM = _acmA;
1160 playoutMode = &_playoutModeA;
1161 bgnMode = &_bgnModeA;
1162 break;
1163 }
1164 case 'B':
1165 {
1166 receiveACM = _acmB;
1167 playoutMode = &_playoutModeB;
1168 bgnMode = &_bgnModeB;
1169 break;
1170 }
1171 default:
1172 receiveACM = _acmA;
1173 }
1174
pbos@webrtc.org0946a562013-04-09 00:28:06 +00001175 int32_t receiveFreqHz = receiveACM->ReceiveFrequency();
1176 int32_t playoutFreqHz = receiveACM->PlayoutFrequency();
niklase@google.com470e71d2011-07-07 08:21:25 +00001177
1178 CHECK_ERROR_MT(receiveFreqHz);
1179 CHECK_ERROR_MT(playoutFreqHz);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001180
niklase@google.com470e71d2011-07-07 08:21:25 +00001181 char bgnString[25];
1182 switch(*bgnMode)
1183 {
1184 case On:
1185 {
1186 *bgnMode = Fade;
1187 strncpy(bgnString, "Fade", 25);
1188 break;
1189 }
1190 case Fade:
1191 {
1192 *bgnMode = Off;
1193 strncpy(bgnString, "OFF", 25);
1194 break;
1195 }
1196 case Off:
1197 {
1198 *bgnMode = On;
1199 strncpy(bgnString, "ON", 25);
1200 break;
1201 }
1202 default:
1203 *bgnMode = On;
1204 strncpy(bgnString, "ON", 25);
1205 }
1206 CHECK_ERROR_MT(receiveACM->SetBackgroundNoiseMode(*bgnMode));
1207 bgnString[24] = '\0';
1208
1209 char playoutString[25];
1210 switch(*playoutMode)
1211 {
1212 case voice:
1213 {
1214 *playoutMode = fax;
1215 strncpy(playoutString, "FAX", 25);
1216 break;
1217 }
1218 case fax:
1219 {
1220 *playoutMode = streaming;
1221 strncpy(playoutString, "Streaming", 25);
1222 break;
1223 }
1224 case streaming:
1225 {
1226 *playoutMode = voice;
1227 strncpy(playoutString, "Voice", 25);
1228 break;
1229 }
1230 default:
1231 *playoutMode = voice;
1232 strncpy(playoutString, "Voice", 25);
1233 }
1234 CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
1235 playoutString[24] = '\0';
1236
1237 if(!_randomTest)
1238 {
1239 fprintf(stdout, "\n");
1240 fprintf(stdout, "In Side %c\n", receiveSide);
1241 fprintf(stdout, "---------------------------------\n");
1242 fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
1243 fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
1244 fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
1245 fprintf(stdout, "Background Noise Mode... %s\n", bgnString);
1246 }
1247}
1248
1249// set/get receiver VAD status & mode.
1250void
1251APITest::TestReceiverVAD(char side)
1252{
1253 AudioCodingModule* myACM;
tina.legrand@webrtc.org731e9ae2011-11-04 07:34:22 +00001254 int* myReceiveVADActivity;
niklase@google.com470e71d2011-07-07 08:21:25 +00001255
1256 if(side == 'A')
1257 {
1258 myACM = _acmA;
1259 myReceiveVADActivity = _receiveVADActivityA;
1260 }
1261 else
1262 {
1263 myACM = _acmB;
1264 myReceiveVADActivity = _receiveVADActivityB;
1265 }
1266
niklase@google.com470e71d2011-07-07 08:21:25 +00001267 ACMVADMode mode = myACM->ReceiveVADMode();
1268
1269 CHECK_ERROR_MT(mode);
1270
1271 if(!_randomTest)
1272 {
1273 fprintf(stdout, "\n\nCurrent Receive VAD at side %c\n", side);
1274 fprintf(stdout, "----------------------------------\n");
niklase@google.com470e71d2011-07-07 08:21:25 +00001275 fprintf(stdout, "mode.......... %d\n", (int)mode);
tina.legrand@webrtc.org731e9ae2011-11-04 07:34:22 +00001276 fprintf(stdout, "VAD Active.... %d\n", myReceiveVADActivity[0]);
1277 fprintf(stdout, "VAD Passive... %d\n", myReceiveVADActivity[1]);
1278 fprintf(stdout, "VAD Unknown... %d\n", myReceiveVADActivity[2]);
niklase@google.com470e71d2011-07-07 08:21:25 +00001279 }
1280
henrike@webrtc.org26d36672011-11-07 23:24:40 +00001281 if(!_randomTest)
niklase@google.com470e71d2011-07-07 08:21:25 +00001282 {
henrike@webrtc.org26d36672011-11-07 23:24:40 +00001283 fprintf(stdout, "\nChange Receive VAD at side %c\n\n", side);
niklase@google.com470e71d2011-07-07 08:21:25 +00001284 }
henrike@webrtc.org26d36672011-11-07 23:24:40 +00001285
1286 switch(mode)
niklase@google.com470e71d2011-07-07 08:21:25 +00001287 {
henrike@webrtc.org26d36672011-11-07 23:24:40 +00001288 case VADNormal:
1289 mode = VADAggr;
1290 break;
1291 case VADLowBitrate:
1292 mode = VADVeryAggr;
1293 break;
1294 case VADAggr:
1295 mode = VADLowBitrate;
1296 break;
1297 case VADVeryAggr:
1298 mode = VADNormal;
1299 break;
1300 default:
1301 mode = VADNormal;
1302
1303 CHECK_ERROR_MT(myACM->SetReceiveVADMode(mode));
niklase@google.com470e71d2011-07-07 08:21:25 +00001304 }
1305 for(int n = 0; n < 3; n++)
1306 {
1307 myReceiveVADActivity[n] = 0;
1308 }
1309}
1310
1311
1312void
1313APITest::TestSendVAD(char side)
1314{
1315 if(_randomTest)
1316 {
1317 return;
1318 }
1319
1320 bool* vad;
1321 bool* dtx;
1322 ACMVADMode* mode;
1323 Channel* myChannel;
1324 AudioCodingModule* myACM;
1325
1326 CodecInst myCodec;
1327 if(!_randomTest)
1328 {
1329 fprintf(stdout, "\n\n");
1330 fprintf(stdout, "-----------------------------------------------\n");
1331 fprintf(stdout, " Test VAD API\n");
1332 fprintf(stdout, "-----------------------------------------------\n");
1333 }
1334
1335 if(side == 'A')
1336 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001337 AudioCodingModule::Codec(_codecCntrA, &myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001338 vad = &_sendVADA;
1339 dtx = &_sendDTXA;
1340 mode = &_sendVADModeA;
1341 myChannel = _channel_A2B;
1342 myACM = _acmA;
1343 }
1344 else
1345 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001346 AudioCodingModule::Codec(_codecCntrB, &myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001347 vad = &_sendVADB;
1348 dtx = &_sendDTXB;
1349 mode = &_sendVADModeB;
1350 myChannel = _channel_B2A;
1351 myACM = _acmB;
1352 }
1353
1354 CheckVADStatus(side);
1355 if(!_randomTest)
1356 {
1357 fprintf(stdout, "\n\n");
1358 }
1359
1360 switch(*mode)
1361 {
1362 case VADNormal:
1363 *vad = true;
1364 *dtx = true;
1365 *mode = VADAggr;
1366 break;
1367 case VADLowBitrate:
1368 *vad = true;
1369 *dtx = true;
1370 *mode = VADVeryAggr;
1371 break;
1372 case VADAggr:
1373 *vad = true;
1374 *dtx = true;
1375 *mode = VADLowBitrate;
1376 break;
1377 case VADVeryAggr:
1378 *vad = false;
1379 *dtx = false;
1380 *mode = VADNormal;
1381 break;
1382 default:
1383 *mode = VADNormal;
1384 }
1385
1386 *dtx = (myCodec.plfreq == 32000)? false:*dtx;
1387
1388 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1389 myChannel->ResetStats();
1390
1391 CheckVADStatus(side);
1392 if(!_randomTest)
1393 {
1394 fprintf(stdout, "\n");
1395 fprintf(stdout, "-----------------------------------------------\n");
1396 }
1397
1398 // Fault Test
1399 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode)-1));
1400 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode)4));
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001401
niklase@google.com470e71d2011-07-07 08:21:25 +00001402
1403
1404}
1405
1406
1407void
1408APITest::CurrentCodec(char side)
1409{
1410 CodecInst myCodec;
niklase@google.com470e71d2011-07-07 08:21:25 +00001411 if(side == 'A')
1412 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001413 _acmA->SendCodec(&myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001414 }
1415 else
1416 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001417 _acmB->SendCodec(&myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001418 }
1419
1420 if(!_randomTest)
1421 {
1422 fprintf(stdout, "\n\n");
1423 fprintf(stdout, "Send codec in Side A\n");
1424 fprintf(stdout, "----------------------------\n");
1425 fprintf(stdout, "Name................. %s\n", myCodec.plname);
1426 fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
1427 fprintf(stdout, "Rate................. %d\n", myCodec.rate);
1428 fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
1429 fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
1430 }
1431
1432 Wait(100);
1433}
1434
1435void
1436APITest::ChangeCodec(char side)
1437{
1438 CodecInst myCodec;
1439 AudioCodingModule* myACM;
pbos@webrtc.org0946a562013-04-09 00:28:06 +00001440 uint8_t* codecCntr;
niklase@google.com470e71d2011-07-07 08:21:25 +00001441 bool* thereIsEncoder;
1442 bool* vad;
1443 bool* dtx;
1444 ACMVADMode* mode;
1445 Channel* myChannel;
niklase@google.com470e71d2011-07-07 08:21:25 +00001446 // Reset and Wait
1447 if(!_randomTest)
1448 {
1449 fprintf(stdout, "Reset Encoder Side A \n");
1450 }
1451 if(side == 'A')
1452 {
1453 myACM = _acmA;
1454 codecCntr = &_codecCntrA;
1455 {
1456 WriteLockScoped wl(_apiTestRWLock);
1457 thereIsEncoder = &_thereIsEncoderA;
1458 }
1459 vad = &_sendVADA;
1460 dtx = &_sendDTXA;
1461 mode = &_sendVADModeA;
1462 myChannel = _channel_A2B;
1463 }
1464 else
1465 {
1466 myACM = _acmB;
1467 codecCntr = &_codecCntrB;
1468 {
1469 WriteLockScoped wl(_apiTestRWLock);
1470 thereIsEncoder = &_thereIsEncoderB;
1471 }
1472 vad = &_sendVADB;
1473 dtx = &_sendDTXB;
1474 mode = &_sendVADModeB;
1475 myChannel = _channel_B2A;
1476 }
1477
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001478 myACM->ResetEncoder();
niklase@google.com470e71d2011-07-07 08:21:25 +00001479 Wait(100);
1480
1481 // Register the next codec
1482 do
1483 {
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001484 *codecCntr = (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1)?
1485 (*codecCntr + 1):0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001486
1487 if(*codecCntr == 0)
1488 {
1489 //printf("Initialize Sender Side A \n");
1490 {
1491 WriteLockScoped wl(_apiTestRWLock);
1492 *thereIsEncoder = false;
1493 }
1494 CHECK_ERROR_MT(myACM->InitializeSender());
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001495 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +00001496
1497 // After Initialization CN is lost, re-register them
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001498 if(AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0)
niklase@google.com470e71d2011-07-07 08:21:25 +00001499 {
1500 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1501 }
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001502 if(AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0)
niklase@google.com470e71d2011-07-07 08:21:25 +00001503 {
1504 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1505 }
1506 // VAD & DTX are disabled after initialization
1507 *vad = false;
1508 *dtx = false;
1509 _writeToFile = false;
1510 }
1511
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +00001512 AudioCodingModule::Codec(*codecCntr, &myCodec);
niklase@google.com470e71d2011-07-07 08:21:25 +00001513 } while(!STR_CASE_CMP(myCodec.plname, "CN") ||
1514 !STR_CASE_CMP(myCodec.plname, "telephone-event") ||
1515 !STR_CASE_CMP(myCodec.plname, "RED"));
1516
1517 if(!_randomTest)
1518 {
1519 fprintf(stdout, "\n====================================================================\n");
1520 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1521 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1522 }
1523 //std::cout<< std::flush;
1524
1525 // NO DTX for supe-wideband codec at this point
1526 if(myCodec.plfreq == 32000)
1527 {
1528 *dtx = false;
1529 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1530
1531 }
1532
1533 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1534 myChannel->ResetStats();
1535 {
1536 WriteLockScoped wl(_apiTestRWLock);
1537 *thereIsEncoder = true;
1538 }
1539 Wait(500);
1540}
1541
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001542
1543void
niklase@google.com470e71d2011-07-07 08:21:25 +00001544APITest::LookForDTMF(char side)
1545{
1546 if(!_randomTest)
1547 {
1548 fprintf(stdout, "\n\nLooking for DTMF Signal in Side %c\n", side);
1549 fprintf(stdout, "----------------------------------------\n");
1550 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001551
niklase@google.com470e71d2011-07-07 08:21:25 +00001552 if(side == 'A')
1553 {
1554 _acmB->RegisterIncomingMessagesCallback(NULL);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +00001555 _acmA->RegisterIncomingMessagesCallback(_dtmfCallback);
niklase@google.com470e71d2011-07-07 08:21:25 +00001556 Wait(1000);
1557 _acmA->RegisterIncomingMessagesCallback(NULL);
1558 }
1559 else
1560 {
1561 _acmA->RegisterIncomingMessagesCallback(NULL);
1562 _acmB->RegisterIncomingMessagesCallback(_dtmfCallback);
1563 Wait(1000);
1564 _acmB->RegisterIncomingMessagesCallback(NULL);
1565 }
1566}
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +00001567
1568} // namespace webrtc
1569