Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      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 
     11 #include "webrtc/modules/audio_coding/main/test/APITest.h"
     12 
     13 #include <ctype.h>
     14 #include <stdio.h>
     15 #include <stdlib.h>
     16 #include <string.h>
     17 
     18 #include <iostream>
     19 #include <ostream>
     20 #include <string>
     21 
     22 #include "testing/gtest/include/gtest/gtest.h"
     23 #include "webrtc/common.h"
     24 #include "webrtc/common_types.h"
     25 #include "webrtc/engine_configurations.h"
     26 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
     27 #include "webrtc/modules/audio_coding/main/test/utility.h"
     28 #include "webrtc/system_wrappers/interface/event_wrapper.h"
     29 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
     30 #include "webrtc/system_wrappers/interface/tick_util.h"
     31 #include "webrtc/system_wrappers/interface/trace.h"
     32 #include "webrtc/test/testsupport/fileutils.h"
     33 
     34 namespace webrtc {
     35 
     36 #define TEST_DURATION_SEC 600
     37 #define NUMBER_OF_SENDER_TESTS 6
     38 #define MAX_FILE_NAME_LENGTH_BYTE 500
     39 #define CHECK_THREAD_NULLITY(myThread, S)                                      \
     40   if(myThread != NULL) {                                                       \
     41     unsigned int i;                                                            \
     42     (myThread)->Start(i);                                                      \
     43   } else {                                                                     \
     44     ADD_FAILURE() << S;                                                        \
     45   }
     46 
     47 void APITest::Wait(uint32_t waitLengthMs) {
     48   if (_randomTest) {
     49     return;
     50   } else {
     51     EventWrapper* myEvent = EventWrapper::Create();
     52     myEvent->Wait(waitLengthMs);
     53     delete myEvent;
     54     return;
     55   }
     56 }
     57 
     58 APITest::APITest(const Config& config)
     59     : _acmA(AudioCodingModule::Create(1)),
     60       _acmB(AudioCodingModule::Create(2)),
     61       _channel_A2B(NULL),
     62       _channel_B2A(NULL),
     63       _writeToFile(true),
     64       _pullEventA(NULL),
     65       _pushEventA(NULL),
     66       _processEventA(NULL),
     67       _apiEventA(NULL),
     68       _pullEventB(NULL),
     69       _pushEventB(NULL),
     70       _processEventB(NULL),
     71       _apiEventB(NULL),
     72       _codecCntrA(0),
     73       _codecCntrB(0),
     74       _thereIsEncoderA(false),
     75       _thereIsEncoderB(false),
     76       _thereIsDecoderA(false),
     77       _thereIsDecoderB(false),
     78       _sendVADA(false),
     79       _sendDTXA(false),
     80       _sendVADModeA(VADNormal),
     81       _sendVADB(false),
     82       _sendDTXB(false),
     83       _sendVADModeB(VADNormal),
     84       _minDelayA(0),
     85       _minDelayB(0),
     86       _dotPositionA(0),
     87       _dotMoveDirectionA(1),
     88       _dotPositionB(39),
     89       _dotMoveDirectionB(-1),
     90       _dtmfCallback(NULL),
     91       _vadCallbackA(NULL),
     92       _vadCallbackB(NULL),
     93       _apiTestRWLock(*RWLockWrapper::CreateRWLock()),
     94       _randomTest(false),
     95       _testNumA(0),
     96       _testNumB(1) {
     97   int n;
     98   for (n = 0; n < 32; n++) {
     99     _payloadUsed[n] = false;
    100   }
    101 
    102   _movingDot[40] = '\0';
    103 
    104   for (int n = 0; n < 40; n++) {
    105     _movingDot[n] = ' ';
    106   }
    107 }
    108 
    109 APITest::~APITest() {
    110   DELETE_POINTER(_channel_A2B);
    111   DELETE_POINTER(_channel_B2A);
    112 
    113   DELETE_POINTER(_pushEventA);
    114   DELETE_POINTER(_pullEventA);
    115   DELETE_POINTER(_processEventA);
    116   DELETE_POINTER(_apiEventA);
    117 
    118   DELETE_POINTER(_pushEventB);
    119   DELETE_POINTER(_pullEventB);
    120   DELETE_POINTER(_processEventB);
    121   DELETE_POINTER(_apiEventB);
    122 
    123   _inFileA.Close();
    124   _outFileA.Close();
    125 
    126   _inFileB.Close();
    127   _outFileB.Close();
    128 
    129   DELETE_POINTER(_dtmfCallback);
    130   DELETE_POINTER(_vadCallbackA);
    131   DELETE_POINTER(_vadCallbackB);
    132 
    133   delete &_apiTestRWLock;
    134 }
    135 
    136 int16_t APITest::SetUp() {
    137   CodecInst dummyCodec;
    138   int lastPayloadType = 0;
    139 
    140   int16_t numCodecs = _acmA->NumberOfCodecs();
    141   for (uint8_t n = 0; n < numCodecs; n++) {
    142     AudioCodingModule::Codec(n, &dummyCodec);
    143     if ((STR_CASE_CMP(dummyCodec.plname, "CN") == 0)
    144         && (dummyCodec.plfreq == 32000)) {
    145       continue;
    146     }
    147 
    148     printf("Register Receive Codec %s  ", dummyCodec.plname);
    149 
    150     if ((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
    151       // Check registration with an already occupied payload type
    152       int currentPayloadType = dummyCodec.pltype;
    153       dummyCodec.pltype = 97;  //lastPayloadType;
    154       CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
    155       dummyCodec.pltype = currentPayloadType;
    156     }
    157 
    158     if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
    159       // test if re-registration works;
    160       CodecInst nextCodec;
    161       int currentPayloadType = dummyCodec.pltype;
    162       AudioCodingModule::Codec(n + 1, &nextCodec);
    163       dummyCodec.pltype = nextCodec.pltype;
    164       if (!FixedPayloadTypeCodec(nextCodec.plname)) {
    165         _acmB->RegisterReceiveCodec(dummyCodec);
    166       }
    167       dummyCodec.pltype = currentPayloadType;
    168     }
    169 
    170     if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
    171       // test if un-registration works;
    172       CodecInst nextCodec;
    173       AudioCodingModule::Codec(n + 1, &nextCodec);
    174       nextCodec.pltype = dummyCodec.pltype;
    175       if (!FixedPayloadTypeCodec(nextCodec.plname)) {
    176         CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
    177         CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
    178       }
    179     }
    180 
    181     CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
    182     printf("   side A done!");
    183     CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
    184     printf("   side B done!\n");
    185 
    186     if (!strcmp(dummyCodec.plname, "CN")) {
    187       CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
    188       CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
    189     }
    190     lastPayloadType = dummyCodec.pltype;
    191     if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
    192       _payloadUsed[lastPayloadType - 96] = true;
    193     }
    194   }
    195   _thereIsDecoderA = true;
    196   _thereIsDecoderB = true;
    197 
    198   // Register Send Codec
    199   AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
    200   CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
    201   _thereIsEncoderA = true;
    202   //
    203   AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
    204   CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
    205   _thereIsEncoderB = true;
    206 
    207   uint16_t frequencyHz;
    208 
    209   printf("\n\nAPI Test\n");
    210   printf("========\n");
    211   printf("Hit enter to accept the default values indicated in []\n\n");
    212 
    213   //--- Input A
    214   std::string file_name = webrtc::test::ResourcePath(
    215       "audio_coding/testfile32kHz", "pcm");
    216   frequencyHz = 32000;
    217   printf("Enter input file at side A [%s]: ", file_name.c_str());
    218   PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
    219   _inFileA.Open(file_name, frequencyHz, "rb", true);
    220 
    221   //--- Output A
    222   std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
    223   printf("Enter output file at side A [%s]: ", out_file_a.c_str());
    224   PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
    225   _outFileA.Open(out_file_a, frequencyHz, "wb");
    226 
    227   //--- Input B
    228   file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
    229   printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
    230   PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
    231   _inFileB.Open(file_name, frequencyHz, "rb", true);
    232 
    233   //--- Output B
    234   std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
    235   printf("Enter output file at side B [%s]: ", out_file_b.c_str());
    236   PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
    237   _outFileB.Open(out_file_b, frequencyHz, "wb");
    238 
    239   //--- Set A-to-B channel
    240   _channel_A2B = new Channel(2);
    241   CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
    242   _channel_A2B->RegisterReceiverACM(_acmB.get());
    243 
    244   //--- Set B-to-A channel
    245   _channel_B2A = new Channel(1);
    246   CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
    247   _channel_B2A->RegisterReceiverACM(_acmA.get());
    248 
    249   //--- EVENT TIMERS
    250   // A
    251   _pullEventA = EventWrapper::Create();
    252   _pushEventA = EventWrapper::Create();
    253   _processEventA = EventWrapper::Create();
    254   _apiEventA = EventWrapper::Create();
    255   // B
    256   _pullEventB = EventWrapper::Create();
    257   _pushEventB = EventWrapper::Create();
    258   _processEventB = EventWrapper::Create();
    259   _apiEventB = EventWrapper::Create();
    260 
    261   //--- I/O params
    262   // A
    263   _outFreqHzA = _outFileA.SamplingFrequency();
    264   // B
    265   _outFreqHzB = _outFileB.SamplingFrequency();
    266 
    267   //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
    268 
    269   char print[11];
    270 
    271   // Create a trace file.
    272   Trace::CreateTrace();
    273   Trace::SetTraceFile(
    274       (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
    275 
    276   printf("\nRandom Test (y/n)?");
    277   EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
    278   print[10] = '\0';
    279   if (strstr(print, "y") != NULL) {
    280     _randomTest = true;
    281     _verbose = false;
    282     _writeToFile = false;
    283   } else {
    284     _randomTest = false;
    285     printf("\nPrint Tests (y/n)? ");
    286     EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
    287     print[10] = '\0';
    288     if (strstr(print, "y") == NULL) {
    289       EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
    290       _verbose = false;
    291     }
    292   }
    293 
    294 #ifdef WEBRTC_DTMF_DETECTION
    295   _dtmfCallback = new DTMFDetector;
    296 #endif
    297   _vadCallbackA = new VADCallback;
    298   _vadCallbackB = new VADCallback;
    299 
    300   return 0;
    301 }
    302 
    303 bool APITest::PushAudioThreadA(void* obj) {
    304   return static_cast<APITest*>(obj)->PushAudioRunA();
    305 }
    306 
    307 bool APITest::PushAudioThreadB(void* obj) {
    308   return static_cast<APITest*>(obj)->PushAudioRunB();
    309 }
    310 
    311 bool APITest::PullAudioThreadA(void* obj) {
    312   return static_cast<APITest*>(obj)->PullAudioRunA();
    313 }
    314 
    315 bool APITest::PullAudioThreadB(void* obj) {
    316   return static_cast<APITest*>(obj)->PullAudioRunB();
    317 }
    318 
    319 bool APITest::ProcessThreadA(void* obj) {
    320   return static_cast<APITest*>(obj)->ProcessRunA();
    321 }
    322 
    323 bool APITest::ProcessThreadB(void* obj) {
    324   return static_cast<APITest*>(obj)->ProcessRunB();
    325 }
    326 
    327 bool APITest::APIThreadA(void* obj) {
    328   return static_cast<APITest*>(obj)->APIRunA();
    329 }
    330 
    331 bool APITest::APIThreadB(void* obj) {
    332   return static_cast<APITest*>(obj)->APIRunB();
    333 }
    334 
    335 bool APITest::PullAudioRunA() {
    336   _pullEventA->Wait(100);
    337   AudioFrame audioFrame;
    338   if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame) < 0) {
    339     bool thereIsDecoder;
    340     {
    341       ReadLockScoped rl(_apiTestRWLock);
    342       thereIsDecoder = _thereIsDecoderA;
    343     }
    344     if (thereIsDecoder) {
    345       fprintf(stderr, "\n>>>>>>    cannot pull audio A       <<<<<<<< \n");
    346     }
    347   } else {
    348     if (_writeToFile) {
    349       _outFileA.Write10MsData(audioFrame);
    350     }
    351   }
    352   return true;
    353 }
    354 
    355 bool APITest::PullAudioRunB() {
    356   _pullEventB->Wait(100);
    357   AudioFrame audioFrame;
    358   if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame) < 0) {
    359     bool thereIsDecoder;
    360     {
    361       ReadLockScoped rl(_apiTestRWLock);
    362       thereIsDecoder = _thereIsDecoderB;
    363     }
    364     if (thereIsDecoder) {
    365       fprintf(stderr, "\n>>>>>>    cannot pull audio B       <<<<<<<< \n");
    366       fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
    367     }
    368   } else {
    369     if (_writeToFile) {
    370       _outFileB.Write10MsData(audioFrame);
    371     }
    372   }
    373   return true;
    374 }
    375 
    376 bool APITest::PushAudioRunA() {
    377   _pushEventA->Wait(100);
    378   AudioFrame audioFrame;
    379   _inFileA.Read10MsData(audioFrame);
    380   if (_acmA->Add10MsData(audioFrame) < 0) {
    381     bool thereIsEncoder;
    382     {
    383       ReadLockScoped rl(_apiTestRWLock);
    384       thereIsEncoder = _thereIsEncoderA;
    385     }
    386     if (thereIsEncoder) {
    387       fprintf(stderr, "\n>>>>        add10MsData at A failed       <<<<\n");
    388     }
    389   }
    390   return true;
    391 }
    392 
    393 bool APITest::PushAudioRunB() {
    394   _pushEventB->Wait(100);
    395   AudioFrame audioFrame;
    396   _inFileB.Read10MsData(audioFrame);
    397   if (_acmB->Add10MsData(audioFrame) < 0) {
    398     bool thereIsEncoder;
    399     {
    400       ReadLockScoped rl(_apiTestRWLock);
    401       thereIsEncoder = _thereIsEncoderB;
    402     }
    403 
    404     if (thereIsEncoder) {
    405       fprintf(stderr, "\n>>>>   cannot add audio to B    <<<<");
    406     }
    407   }
    408 
    409   return true;
    410 }
    411 
    412 bool APITest::ProcessRunA() {
    413   _processEventA->Wait(100);
    414   if (_acmA->Process() < 0) {
    415     // do not print error message if there is no encoder
    416     bool thereIsEncoder;
    417     {
    418       ReadLockScoped rl(_apiTestRWLock);
    419       thereIsEncoder = _thereIsEncoderA;
    420     }
    421 
    422     if (thereIsEncoder) {
    423       fprintf(stderr, "\n>>>>>      Process Failed at A     <<<<<\n");
    424     }
    425   }
    426   return true;
    427 }
    428 
    429 bool APITest::ProcessRunB() {
    430   _processEventB->Wait(100);
    431   if (_acmB->Process() < 0) {
    432     bool thereIsEncoder;
    433     {
    434       ReadLockScoped rl(_apiTestRWLock);
    435       thereIsEncoder = _thereIsEncoderB;
    436     }
    437     if (thereIsEncoder) {
    438       fprintf(stderr, "\n>>>>>      Process Failed at B     <<<<<\n");
    439     }
    440   }
    441   return true;
    442 }
    443 
    444 /*/
    445  *
    446  * In side A we test the APIs which are related to sender Side.
    447  *
    448 /*/
    449 
    450 void APITest::RunTest(char thread) {
    451   int testNum;
    452   {
    453     WriteLockScoped cs(_apiTestRWLock);
    454     if (thread == 'A') {
    455       _testNumA = (_testNumB + 1 + (rand() % 4)) % 5;
    456       testNum = _testNumA;
    457 
    458       _movingDot[_dotPositionA] = ' ';
    459       if (_dotPositionA == 0) {
    460         _dotMoveDirectionA = 1;
    461       }
    462       if (_dotPositionA == 19) {
    463         _dotMoveDirectionA = -1;
    464       }
    465       _dotPositionA += _dotMoveDirectionA;
    466       _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
    467     } else {
    468       _testNumB = (_testNumA + 1 + (rand() % 4)) % 5;
    469       testNum = _testNumB;
    470 
    471       _movingDot[_dotPositionB] = ' ';
    472       if (_dotPositionB == 20) {
    473         _dotMoveDirectionB = 1;
    474       }
    475       if (_dotPositionB == 39) {
    476         _dotMoveDirectionB = -1;
    477       }
    478       _dotPositionB += _dotMoveDirectionB;
    479       _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
    480     }
    481     //fprintf(stderr, "%c: %d \n", thread, testNum);
    482     //fflush(stderr);
    483   }
    484   switch (testNum) {
    485     case 0:
    486       CurrentCodec('A');
    487       ChangeCodec('A');
    488       break;
    489     case 1:
    490       TestPlayout('B');
    491       break;
    492     case 2:
    493       if (!_randomTest) {
    494         fprintf(stdout, "\nTesting Delay ...\n");
    495       }
    496       TestDelay('A');
    497       break;
    498     case 3:
    499       TestSendVAD('A');
    500       break;
    501     case 4:
    502       TestRegisteration('A');
    503       break;
    504     default:
    505       fprintf(stderr, "Wrong Test Number\n");
    506       getchar();
    507       exit(1);
    508   }
    509 }
    510 
    511 bool APITest::APIRunA() {
    512   _apiEventA->Wait(50);
    513 
    514   bool randomTest;
    515   {
    516     ReadLockScoped rl(_apiTestRWLock);
    517     randomTest = _randomTest;
    518   }
    519   if (randomTest) {
    520     RunTest('A');
    521   } else {
    522     CurrentCodec('A');
    523     ChangeCodec('A');
    524     TestPlayout('B');
    525     if (_codecCntrA == 0) {
    526       fprintf(stdout, "\nTesting Delay ...\n");
    527       TestDelay('A');
    528     }
    529     // VAD TEST
    530     TestSendVAD('A');
    531     TestRegisteration('A');
    532   }
    533   return true;
    534 }
    535 
    536 bool APITest::APIRunB() {
    537   _apiEventB->Wait(50);
    538   bool randomTest;
    539   {
    540     ReadLockScoped rl(_apiTestRWLock);
    541     randomTest = _randomTest;
    542   }
    543   //_apiEventB->Wait(2000);
    544   if (randomTest) {
    545     RunTest('B');
    546   }
    547 
    548   return true;
    549 }
    550 
    551 void APITest::Perform() {
    552   SetUp();
    553 
    554   //--- THREADS
    555   // A
    556   // PUSH
    557   ThreadWrapper* myPushAudioThreadA = ThreadWrapper::CreateThread(
    558       PushAudioThreadA, this, kNormalPriority, "PushAudioThreadA");
    559   CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
    560   // PULL
    561   ThreadWrapper* myPullAudioThreadA = ThreadWrapper::CreateThread(
    562       PullAudioThreadA, this, kNormalPriority, "PullAudioThreadA");
    563   CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
    564   // Process
    565   ThreadWrapper* myProcessThreadA = ThreadWrapper::CreateThread(
    566       ProcessThreadA, this, kNormalPriority, "ProcessThreadA");
    567   CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
    568   // API
    569   ThreadWrapper* myAPIThreadA = ThreadWrapper::CreateThread(APIThreadA, this,
    570                                                             kNormalPriority,
    571                                                             "APIThreadA");
    572   CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
    573   // B
    574   // PUSH
    575   ThreadWrapper* myPushAudioThreadB = ThreadWrapper::CreateThread(
    576       PushAudioThreadB, this, kNormalPriority, "PushAudioThreadB");
    577   CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
    578   // PULL
    579   ThreadWrapper* myPullAudioThreadB = ThreadWrapper::CreateThread(
    580       PullAudioThreadB, this, kNormalPriority, "PullAudioThreadB");
    581   CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
    582   // Process
    583   ThreadWrapper* myProcessThreadB = ThreadWrapper::CreateThread(
    584       ProcessThreadB, this, kNormalPriority, "ProcessThreadB");
    585   CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
    586   // API
    587   ThreadWrapper* myAPIThreadB = ThreadWrapper::CreateThread(APIThreadB, this,
    588                                                             kNormalPriority,
    589                                                             "APIThreadB");
    590   CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
    591 
    592   //_apiEventA->StartTimer(true, 5000);
    593   //_apiEventB->StartTimer(true, 5000);
    594 
    595   _processEventA->StartTimer(true, 10);
    596   _processEventB->StartTimer(true, 10);
    597 
    598   _pullEventA->StartTimer(true, 10);
    599   _pullEventB->StartTimer(true, 10);
    600 
    601   _pushEventA->StartTimer(true, 10);
    602   _pushEventB->StartTimer(true, 10);
    603 
    604   // Keep main thread waiting for sender/receiver
    605   // threads to complete
    606   EventWrapper* completeEvent = EventWrapper::Create();
    607   uint64_t startTime = TickTime::MillisecondTimestamp();
    608   uint64_t currentTime;
    609   // Run test in 2 minutes (120000 ms).
    610   do {
    611     {
    612       //ReadLockScoped rl(_apiTestRWLock);
    613       //fprintf(stderr, "\r%s", _movingDot);
    614     }
    615     //fflush(stderr);
    616     completeEvent->Wait(50);
    617     currentTime = TickTime::MillisecondTimestamp();
    618   } while ((currentTime - startTime) < 120000);
    619 
    620   //completeEvent->Wait(0xFFFFFFFF);
    621   //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
    622   delete completeEvent;
    623 
    624   myPushAudioThreadA->Stop();
    625   myPullAudioThreadA->Stop();
    626   myProcessThreadA->Stop();
    627   myAPIThreadA->Stop();
    628 
    629   delete myPushAudioThreadA;
    630   delete myPullAudioThreadA;
    631   delete myProcessThreadA;
    632   delete myAPIThreadA;
    633 
    634   myPushAudioThreadB->Stop();
    635   myPullAudioThreadB->Stop();
    636   myProcessThreadB->Stop();
    637   myAPIThreadB->Stop();
    638 
    639   delete myPushAudioThreadB;
    640   delete myPullAudioThreadB;
    641   delete myProcessThreadB;
    642   delete myAPIThreadB;
    643 }
    644 
    645 void APITest::CheckVADStatus(char side) {
    646 
    647   bool dtxEnabled;
    648   bool vadEnabled;
    649   ACMVADMode vadMode;
    650 
    651   if (side == 'A') {
    652     _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
    653     _acmA->RegisterVADCallback(NULL);
    654     _vadCallbackA->Reset();
    655     _acmA->RegisterVADCallback(_vadCallbackA);
    656 
    657     if (!_randomTest) {
    658       if (_verbose) {
    659         fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
    660                 vadEnabled ? "ON" : "OFF", (int) vadMode);
    661         Wait(5000);
    662         fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
    663       } else {
    664         Wait(5000);
    665         fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
    666                 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
    667                 (int) vadMode, _channel_A2B->BitRate());
    668       }
    669       _vadCallbackA->PrintFrameTypes();
    670     }
    671 
    672     if (dtxEnabled != _sendDTXA) {
    673       fprintf(stderr, ">>>   Error Enabling DTX    <<<\n");
    674     }
    675     if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
    676       fprintf(stderr, ">>>   Error Enabling VAD    <<<\n");
    677     }
    678     if ((vadMode != _sendVADModeA) && vadEnabled) {
    679       fprintf(stderr, ">>>   Error setting VAD-mode    <<<\n");
    680     }
    681   } else {
    682     _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
    683 
    684     _acmB->RegisterVADCallback(NULL);
    685     _vadCallbackB->Reset();
    686     _acmB->RegisterVADCallback(_vadCallbackB);
    687 
    688     if (!_randomTest) {
    689       if (_verbose) {
    690         fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
    691                 vadEnabled ? "ON" : "OFF", (int) vadMode);
    692         Wait(5000);
    693         fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
    694       } else {
    695         Wait(5000);
    696         fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
    697                 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
    698                 (int) vadMode, _channel_B2A->BitRate());
    699       }
    700       _vadCallbackB->PrintFrameTypes();
    701     }
    702 
    703     if (dtxEnabled != _sendDTXB) {
    704       fprintf(stderr, ">>>   Error Enabling DTX    <<<\n");
    705     }
    706     if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
    707       fprintf(stderr, ">>>   Error Enabling VAD    <<<\n");
    708     }
    709     if ((vadMode != _sendVADModeB) && vadEnabled) {
    710       fprintf(stderr, ">>>   Error setting VAD-mode    <<<\n");
    711     }
    712   }
    713 }
    714 
    715 // Set Min delay, get delay, playout timestamp
    716 void APITest::TestDelay(char side) {
    717   AudioCodingModule* myACM;
    718   Channel* myChannel;
    719   int32_t* myMinDelay;
    720   EventWrapper* myEvent = EventWrapper::Create();
    721 
    722   uint32_t inTimestamp = 0;
    723   uint32_t outTimestamp = 0;
    724   double estimDelay = 0;
    725 
    726   double averageEstimDelay = 0;
    727   double averageDelay = 0;
    728 
    729   CircularBuffer estimDelayCB(100);
    730   estimDelayCB.SetArithMean(true);
    731 
    732   if (side == 'A') {
    733     myACM = _acmA.get();
    734     myChannel = _channel_B2A;
    735     myMinDelay = &_minDelayA;
    736   } else {
    737     myACM = _acmB.get();
    738     myChannel = _channel_A2B;
    739     myMinDelay = &_minDelayB;
    740   }
    741 
    742   CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
    743 
    744   inTimestamp = myChannel->LastInTimestamp();
    745   CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
    746 
    747   if (!_randomTest) {
    748     myEvent->StartTimer(true, 30);
    749     int n = 0;
    750     int settlePoint = 5000;
    751     while (n < settlePoint + 400) {
    752       myEvent->Wait(1000);
    753 
    754       inTimestamp = myChannel->LastInTimestamp();
    755       CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
    756 
    757       //std::cout << outTimestamp << std::endl << std::flush;
    758       estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
    759           / ((double) myACM->ReceiveFrequency() / 1000.0);
    760 
    761       estimDelayCB.Update(estimDelay);
    762 
    763       estimDelayCB.ArithMean(averageEstimDelay);
    764       //printf("\n %6.1f \n", estimDelay);
    765       //std::cout << " " << std::flush;
    766 
    767       if (_verbose) {
    768         fprintf(stdout,
    769                 "\rExpected: %4d,    retreived: %6.1f,   measured: %6.1f",
    770                 *myMinDelay, averageDelay, averageEstimDelay);
    771         std::cout << " " << std::flush;
    772       }
    773       if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
    774         settlePoint = n;
    775       }
    776       n++;
    777     }
    778     myEvent->StopTimer();
    779   }
    780 
    781   if ((!_verbose) && (!_randomTest)) {
    782     fprintf(stdout, "\nExpected: %4d,    retreived: %6.1f,   measured: %6.1f",
    783             *myMinDelay, averageDelay, averageEstimDelay);
    784   }
    785 
    786   *myMinDelay = (rand() % 1000) + 1;
    787 
    788   ACMNetworkStatistics networkStat;
    789   CHECK_ERROR_MT(myACM->NetworkStatistics(&networkStat));
    790 
    791   if (!_randomTest) {
    792     fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
    793     fprintf(stdout, "--------------------------------------\n");
    794     fprintf(stdout, "buffer-size............. %d\n",
    795             networkStat.currentBufferSize);
    796     fprintf(stdout, "Preferred buffer-size... %d\n",
    797             networkStat.preferredBufferSize);
    798     fprintf(stdout, "Peaky jitter mode........%d\n",
    799             networkStat.jitterPeaksFound);
    800     fprintf(stdout, "packet-size rate........ %d\n",
    801             networkStat.currentPacketLossRate);
    802     fprintf(stdout, "discard rate............ %d\n",
    803             networkStat.currentDiscardRate);
    804     fprintf(stdout, "expand rate............. %d\n",
    805             networkStat.currentExpandRate);
    806     fprintf(stdout, "Preemptive rate......... %d\n",
    807             networkStat.currentPreemptiveRate);
    808     fprintf(stdout, "Accelerate rate......... %d\n",
    809             networkStat.currentAccelerateRate);
    810     fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
    811     fprintf(stdout, "Mean waiting time....... %d\n",
    812             networkStat.meanWaitingTimeMs);
    813     fprintf(stdout, "Median waiting time..... %d\n",
    814             networkStat.medianWaitingTimeMs);
    815     fprintf(stdout, "Min waiting time........ %d\n",
    816             networkStat.minWaitingTimeMs);
    817     fprintf(stdout, "Max waiting time........ %d\n",
    818             networkStat.maxWaitingTimeMs);
    819   }
    820 
    821   CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
    822 
    823   if (!_randomTest) {
    824     myEvent->Wait(500);
    825     fprintf(stdout, "\n");
    826     fprintf(stdout, "\n");
    827   }
    828   delete myEvent;
    829 }
    830 
    831 // Unregister a codec & register again.
    832 void APITest::TestRegisteration(char sendSide) {
    833   AudioCodingModule* sendACM;
    834   AudioCodingModule* receiveACM;
    835   bool* thereIsDecoder;
    836   EventWrapper* myEvent = EventWrapper::Create();
    837 
    838   if (!_randomTest) {
    839     fprintf(stdout, "\n\n");
    840     fprintf(stdout,
    841             "---------------------------------------------------------\n");
    842     fprintf(stdout, "           Unregister/register Receive Codec\n");
    843     fprintf(stdout,
    844             "---------------------------------------------------------\n");
    845   }
    846 
    847   switch (sendSide) {
    848     case 'A': {
    849       sendACM = _acmA.get();
    850       receiveACM = _acmB.get();
    851       thereIsDecoder = &_thereIsDecoderB;
    852       break;
    853     }
    854     case 'B': {
    855       sendACM = _acmB.get();
    856       receiveACM = _acmA.get();
    857       thereIsDecoder = &_thereIsDecoderA;
    858       break;
    859     }
    860     default:
    861       fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
    862               sendSide);
    863       exit(-1);
    864   }
    865 
    866   CodecInst myCodec;
    867   if (sendACM->SendCodec(&myCodec) < 0) {
    868     AudioCodingModule::Codec(_codecCntrA, &myCodec);
    869   }
    870 
    871   if (!_randomTest) {
    872     fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
    873     fflush (stdout);
    874   }
    875   {
    876     WriteLockScoped wl(_apiTestRWLock);
    877     *thereIsDecoder = false;
    878   }
    879   //myEvent->Wait(20);
    880   CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
    881   Wait(1000);
    882 
    883   int currentPayload = myCodec.pltype;
    884 
    885   if (!FixedPayloadTypeCodec(myCodec.plname)) {
    886     int32_t i;
    887     for (i = 0; i < 32; i++) {
    888       if (!_payloadUsed[i]) {
    889         if (!_randomTest) {
    890           fprintf(stdout,
    891                   "Register receive codec with new Payload, AUDIO BACK.\n");
    892         }
    893         //myCodec.pltype = i + 96;
    894         //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
    895         //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
    896         //myEvent->Wait(20);
    897         //{
    898         //    WriteLockScoped wl(_apiTestRWLock);
    899         //    *thereIsDecoder = true;
    900         //}
    901         Wait(1000);
    902 
    903         if (!_randomTest) {
    904           fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
    905         }
    906         //{
    907         //    WriteLockScoped wl(_apiTestRWLock);
    908         //    *thereIsDecoder = false;
    909         //}
    910         //myEvent->Wait(20);
    911         //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
    912         Wait(1000);
    913 
    914         myCodec.pltype = currentPayload;
    915         if (!_randomTest) {
    916           fprintf(stdout,
    917                   "Register receive codec with default Payload, AUDIO BACK.\n");
    918           fflush (stdout);
    919         }
    920         CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
    921         //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
    922         myEvent->Wait(20);
    923         {
    924           WriteLockScoped wl(_apiTestRWLock);
    925           *thereIsDecoder = true;
    926         }
    927         Wait(1000);
    928 
    929         break;
    930       }
    931     }
    932     if (i == 32) {
    933       CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
    934       {
    935         WriteLockScoped wl(_apiTestRWLock);
    936         *thereIsDecoder = true;
    937       }
    938     }
    939   } else {
    940     if (!_randomTest) {
    941       fprintf(stdout,
    942               "Register receive codec with fixed Payload, AUDIO BACK.\n");
    943       fflush (stdout);
    944     }
    945     CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
    946     //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
    947     //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
    948     myEvent->Wait(20);
    949     {
    950       WriteLockScoped wl(_apiTestRWLock);
    951       *thereIsDecoder = true;
    952     }
    953   }
    954   delete myEvent;
    955   if (!_randomTest) {
    956     fprintf(stdout,
    957             "---------------------------------------------------------\n");
    958   }
    959 }
    960 
    961 // Playout Mode, background noise mode.
    962 // Receiver Frequency, playout frequency.
    963 void APITest::TestPlayout(char receiveSide) {
    964   AudioCodingModule* receiveACM;
    965   AudioPlayoutMode* playoutMode = NULL;
    966   switch (receiveSide) {
    967     case 'A': {
    968       receiveACM = _acmA.get();
    969       playoutMode = &_playoutModeA;
    970       break;
    971     }
    972     case 'B': {
    973       receiveACM = _acmB.get();
    974       playoutMode = &_playoutModeB;
    975       break;
    976     }
    977     default:
    978       receiveACM = _acmA.get();
    979   }
    980 
    981   int32_t receiveFreqHz = receiveACM->ReceiveFrequency();
    982   int32_t playoutFreqHz = receiveACM->PlayoutFrequency();
    983 
    984   CHECK_ERROR_MT(receiveFreqHz);
    985   CHECK_ERROR_MT(playoutFreqHz);
    986 
    987 
    988   char playoutString[25];
    989   switch (*playoutMode) {
    990     case voice: {
    991       *playoutMode = fax;
    992       strncpy(playoutString, "FAX", 25);
    993       break;
    994     }
    995     case fax: {
    996       *playoutMode = streaming;
    997       strncpy(playoutString, "Streaming", 25);
    998       break;
    999     }
   1000     case streaming: {
   1001       *playoutMode = voice;
   1002       strncpy(playoutString, "Voice", 25);
   1003       break;
   1004     }
   1005     default:
   1006       *playoutMode = voice;
   1007       strncpy(playoutString, "Voice", 25);
   1008   }
   1009   CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
   1010   playoutString[24] = '\0';
   1011 
   1012   if (!_randomTest) {
   1013     fprintf(stdout, "\n");
   1014     fprintf(stdout, "In Side %c\n", receiveSide);
   1015     fprintf(stdout, "---------------------------------\n");
   1016     fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
   1017     fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
   1018     fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
   1019   }
   1020 }
   1021 
   1022 void APITest::TestSendVAD(char side) {
   1023   if (_randomTest) {
   1024     return;
   1025   }
   1026 
   1027   bool* vad;
   1028   bool* dtx;
   1029   ACMVADMode* mode;
   1030   Channel* myChannel;
   1031   AudioCodingModule* myACM;
   1032 
   1033   CodecInst myCodec;
   1034   if (!_randomTest) {
   1035     fprintf(stdout, "\n\n");
   1036     fprintf(stdout, "-----------------------------------------------\n");
   1037     fprintf(stdout, "                Test VAD API\n");
   1038     fprintf(stdout, "-----------------------------------------------\n");
   1039   }
   1040 
   1041   if (side == 'A') {
   1042     AudioCodingModule::Codec(_codecCntrA, &myCodec);
   1043     vad = &_sendVADA;
   1044     dtx = &_sendDTXA;
   1045     mode = &_sendVADModeA;
   1046     myChannel = _channel_A2B;
   1047     myACM = _acmA.get();
   1048   } else {
   1049     AudioCodingModule::Codec(_codecCntrB, &myCodec);
   1050     vad = &_sendVADB;
   1051     dtx = &_sendDTXB;
   1052     mode = &_sendVADModeB;
   1053     myChannel = _channel_B2A;
   1054     myACM = _acmB.get();
   1055   }
   1056 
   1057   CheckVADStatus(side);
   1058   if (!_randomTest) {
   1059     fprintf(stdout, "\n\n");
   1060   }
   1061 
   1062   switch (*mode) {
   1063     case VADNormal:
   1064       *vad = true;
   1065       *dtx = true;
   1066       *mode = VADAggr;
   1067       break;
   1068     case VADLowBitrate:
   1069       *vad = true;
   1070       *dtx = true;
   1071       *mode = VADVeryAggr;
   1072       break;
   1073     case VADAggr:
   1074       *vad = true;
   1075       *dtx = true;
   1076       *mode = VADLowBitrate;
   1077       break;
   1078     case VADVeryAggr:
   1079       *vad = false;
   1080       *dtx = false;
   1081       *mode = VADNormal;
   1082       break;
   1083     default:
   1084       *mode = VADNormal;
   1085   }
   1086 
   1087   *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
   1088 
   1089   CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
   1090   myChannel->ResetStats();
   1091 
   1092   CheckVADStatus(side);
   1093   if (!_randomTest) {
   1094     fprintf(stdout, "\n");
   1095     fprintf(stdout, "-----------------------------------------------\n");
   1096   }
   1097 
   1098   // Fault Test
   1099   CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
   1100   CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
   1101 
   1102 }
   1103 
   1104 void APITest::CurrentCodec(char side) {
   1105   CodecInst myCodec;
   1106   if (side == 'A') {
   1107     _acmA->SendCodec(&myCodec);
   1108   } else {
   1109     _acmB->SendCodec(&myCodec);
   1110   }
   1111 
   1112   if (!_randomTest) {
   1113     fprintf(stdout, "\n\n");
   1114     fprintf(stdout, "Send codec in Side A\n");
   1115     fprintf(stdout, "----------------------------\n");
   1116     fprintf(stdout, "Name................. %s\n", myCodec.plname);
   1117     fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
   1118     fprintf(stdout, "Rate................. %d\n", myCodec.rate);
   1119     fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
   1120     fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
   1121   }
   1122 
   1123   Wait(100);
   1124 }
   1125 
   1126 void APITest::ChangeCodec(char side) {
   1127   CodecInst myCodec;
   1128   AudioCodingModule* myACM;
   1129   uint8_t* codecCntr;
   1130   bool* thereIsEncoder;
   1131   bool* vad;
   1132   bool* dtx;
   1133   ACMVADMode* mode;
   1134   Channel* myChannel;
   1135   // Reset and Wait
   1136   if (!_randomTest) {
   1137     fprintf(stdout, "Reset Encoder Side A \n");
   1138   }
   1139   if (side == 'A') {
   1140     myACM = _acmA.get();
   1141     codecCntr = &_codecCntrA;
   1142     {
   1143       WriteLockScoped wl(_apiTestRWLock);
   1144       thereIsEncoder = &_thereIsEncoderA;
   1145     }
   1146     vad = &_sendVADA;
   1147     dtx = &_sendDTXA;
   1148     mode = &_sendVADModeA;
   1149     myChannel = _channel_A2B;
   1150   } else {
   1151     myACM = _acmB.get();
   1152     codecCntr = &_codecCntrB;
   1153     {
   1154       WriteLockScoped wl(_apiTestRWLock);
   1155       thereIsEncoder = &_thereIsEncoderB;
   1156     }
   1157     vad = &_sendVADB;
   1158     dtx = &_sendDTXB;
   1159     mode = &_sendVADModeB;
   1160     myChannel = _channel_B2A;
   1161   }
   1162 
   1163   myACM->ResetEncoder();
   1164   Wait(100);
   1165 
   1166   // Register the next codec
   1167   do {
   1168     *codecCntr =
   1169         (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
   1170             (*codecCntr + 1) : 0;
   1171 
   1172     if (*codecCntr == 0) {
   1173       //printf("Initialize Sender Side A \n");
   1174       {
   1175         WriteLockScoped wl(_apiTestRWLock);
   1176         *thereIsEncoder = false;
   1177       }
   1178       CHECK_ERROR_MT(myACM->InitializeSender());
   1179       Wait(1000);
   1180 
   1181       // After Initialization CN is lost, re-register them
   1182       if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
   1183         CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
   1184       }
   1185       if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
   1186         CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
   1187       }
   1188       // VAD & DTX are disabled after initialization
   1189       *vad = false;
   1190       *dtx = false;
   1191       _writeToFile = false;
   1192     }
   1193 
   1194     AudioCodingModule::Codec(*codecCntr, &myCodec);
   1195   } while (!STR_CASE_CMP(myCodec.plname, "CN")
   1196       || !STR_CASE_CMP(myCodec.plname, "telephone-event")
   1197       || !STR_CASE_CMP(myCodec.plname, "RED"));
   1198 
   1199   if (!_randomTest) {
   1200     fprintf(stdout,"\n=====================================================\n");
   1201     fprintf(stdout, "      Registering New Codec %s, %d kHz, %d kbps\n",
   1202             myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
   1203   }
   1204   //std::cout<< std::flush;
   1205 
   1206   // NO DTX for supe-wideband codec at this point
   1207   if (myCodec.plfreq == 32000) {
   1208     *dtx = false;
   1209     CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
   1210 
   1211   }
   1212 
   1213   CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
   1214   myChannel->ResetStats();
   1215   {
   1216     WriteLockScoped wl(_apiTestRWLock);
   1217     *thereIsEncoder = true;
   1218   }
   1219   Wait(500);
   1220 }
   1221 
   1222 }  // namespace webrtc
   1223