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