/* * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "TestFEC.h" #include #include #include "audio_coding_module_typedefs.h" #include "common_types.h" #include "engine_configurations.h" #include "trace.h" #include "testsupport/fileutils.h" #include "utility.h" namespace webrtc { TestFEC::TestFEC(int testMode): _acmA(NULL), _acmB(NULL), _channelA2B(NULL), _testCntr(0) { _testMode = testMode; } TestFEC::~TestFEC() { if(_acmA != NULL) { AudioCodingModule::Destroy(_acmA); _acmA = NULL; } if(_acmB != NULL) { AudioCodingModule::Destroy(_acmB); _acmB = NULL; } if(_channelA2B != NULL) { delete _channelA2B; _channelA2B = NULL; } } void TestFEC::Perform() { if(_testMode == 0) { printf("Running FEC Test"); WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1, "---------- TestFEC ----------"); } const std::string file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); _inFileA.Open(file_name, 32000, "rb"); bool fecEnabled; _acmA = AudioCodingModule::Create(0); _acmB = AudioCodingModule::Create(1); _acmA->InitializeReceiver(); _acmB->InitializeReceiver(); uint8_t numEncoders = _acmA->NumberOfCodecs(); CodecInst myCodecParam; if(_testMode != 0) { printf("Registering codecs at receiver... \n"); } for(uint8_t n = 0; n < numEncoders; n++) { _acmB->Codec(n, &myCodecParam); if(_testMode != 0) { printf("%s\n", myCodecParam.plname); } _acmB->RegisterReceiveCodec(myCodecParam); } // Create and connect the channel _channelA2B = new Channel; _acmA->RegisterTransportCallback(_channelA2B); _channelA2B->RegisterReceiverACM(_acmB); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } #ifndef WEBRTC_CODEC_G722 printf("G722 needs to be activated to run this test\n"); exit(-1); #endif char nameG722[] = "G722"; RegisterSendCodec('A', nameG722, 16000); char nameCN[] = "CN"; RegisterSendCodec('A', nameCN, 16000); char nameRED[] = "RED"; RegisterSendCodec('A', nameRED); OpenOutFile(_testCntr); SetVAD(true, true, VADAggr); _acmA->SetFECStatus(false); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } _acmA->SetFECStatus(true); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } OpenOutFile(_testCntr); Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } char nameISAC[] = "iSAC"; RegisterSendCodec('A',nameISAC, 16000); OpenOutFile(_testCntr); SetVAD(true, true, VADVeryAggr); _acmA->SetFECStatus(false); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } _acmA->SetFECStatus(true); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } OpenOutFile(_testCntr); Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } RegisterSendCodec('A', nameISAC, 32000); OpenOutFile(_testCntr); SetVAD(true, true, VADVeryAggr); _acmA->SetFECStatus(false); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } _acmA->SetFECStatus(true); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } OpenOutFile(_testCntr); Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } RegisterSendCodec('A', nameISAC, 32000); OpenOutFile(_testCntr); SetVAD(false, false, VADNormal); _acmA->SetFECStatus(true); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); RegisterSendCodec('A', nameISAC, 16000); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); RegisterSendCodec('A', nameISAC, 32000); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); RegisterSendCodec('A', nameISAC, 16000); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); _outFileB.Close(); _channelA2B->SetFECTestWithPacketLoss(true); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } RegisterSendCodec('A',nameG722); RegisterSendCodec('A', nameCN, 16000); OpenOutFile(_testCntr); SetVAD(true, true, VADAggr); _acmA->SetFECStatus(false); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } _acmA->SetFECStatus(true); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } OpenOutFile(_testCntr); Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } RegisterSendCodec('A', nameISAC, 16000); OpenOutFile(_testCntr); SetVAD(true, true, VADVeryAggr); _acmA->SetFECStatus(false); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } _acmA->SetFECStatus(true); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } OpenOutFile(_testCntr); Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } RegisterSendCodec('A', nameISAC, 32000); OpenOutFile(_testCntr); SetVAD(true, true, VADVeryAggr); _acmA->SetFECStatus(false); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } _acmA->SetFECStatus(true); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } OpenOutFile(_testCntr); Run(); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); printf("%d ",_testCntr++); } else { printf("."); } RegisterSendCodec('A', nameISAC, 32000); OpenOutFile(_testCntr); SetVAD(false, false, VADNormal); _acmA->SetFECStatus(true); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); RegisterSendCodec('A', nameISAC, 16000); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); RegisterSendCodec('A', nameISAC, 32000); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); RegisterSendCodec('A', nameISAC, 16000); fecEnabled = _acmA->FECStatus(); if(_testMode != 0) { printf("FEC currently %s\n",(fecEnabled?"ON":"OFF")); DisplaySendReceiveCodec(); } Run(); _outFileB.Close(); if(_testMode == 0) { printf("Done!\n"); } } int32_t TestFEC::SetVAD(bool enableDTX, bool enableVAD, ACMVADMode vadMode) { if(_testMode != 0) { printf("DTX %s; VAD %s; VAD-Mode %d\n", enableDTX? "ON":"OFF", enableVAD? "ON":"OFF", (int16_t)vadMode); } return _acmA->SetVAD(enableDTX, enableVAD, vadMode); } int16_t TestFEC::RegisterSendCodec(char side, char* codecName, int32_t samplingFreqHz) { if(_testMode != 0) { if(samplingFreqHz > 0) { printf("Registering %s-%d for side %c\n", codecName, samplingFreqHz, side); } else { printf("Registering %s for side %c\n", codecName, side); } } std::cout << std::flush; AudioCodingModule* myACM; switch(side) { case 'A': { myACM = _acmA; break; } case 'B': { myACM = _acmB; break; } default: return -1; } if(myACM == NULL) { assert(false); return -1; } CodecInst myCodecParam; CHECK_ERROR(AudioCodingModule::Codec(codecName, &myCodecParam, samplingFreqHz, 1)); CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam)); // initialization was succesful return 0; } void TestFEC::Run() { AudioFrame audioFrame; uint16_t msecPassed = 0; uint32_t secPassed = 0; int32_t outFreqHzB = _outFileB.SamplingFrequency(); while(!_inFileA.EndOfFile()) { _inFileA.Read10MsData(audioFrame); CHECK_ERROR(_acmA->Add10MsData(audioFrame)); CHECK_ERROR(_acmA->Process()); CHECK_ERROR(_acmB->PlayoutData10Ms(outFreqHzB, &audioFrame)); _outFileB.Write10MsData(audioFrame.data_, audioFrame.samples_per_channel_); msecPassed += 10; if(msecPassed >= 1000) { msecPassed = 0; secPassed++; } if(((secPassed%5) == 4) && (msecPassed == 0) && (_testCntr > 14)) { printf("%3u:%3u ", secPassed, msecPassed); _acmA->SetFECStatus(false); printf("FEC currently %s\n",(_acmA->FECStatus()?"ON":"OFF")); } if(((secPassed%5) == 4) && (msecPassed >= 990) && (_testCntr > 14)) { printf("%3u:%3u ", secPassed, msecPassed); _acmA->SetFECStatus(true); printf("FEC currently %s\n",(_acmA->FECStatus()?"ON":"OFF")); } } _inFileA.Rewind(); } void TestFEC::OpenOutFile(int16_t test_number) { std::string file_name; std::stringstream file_stream; file_stream << webrtc::test::OutputPath(); if (_testMode == 0) { file_stream << "TestFEC_autoFile_"; } else { file_stream << "TestFEC_outFile_"; } file_stream << test_number << ".pcm"; file_name = file_stream.str(); _outFileB.Open(file_name, 16000, "wb"); } void TestFEC::DisplaySendReceiveCodec() { CodecInst myCodecParam; _acmA->SendCodec(&myCodecParam); printf("%s -> ", myCodecParam.plname); _acmB->ReceiveCodec(&myCodecParam); printf("%s\n", myCodecParam.plname); } } // namespace webrtc