Files
platform-external-webrtc/webrtc/modules/audio_coding/main/test/iSACTest.cc
tommi@webrtc.org 9509fbfc30 Split EventWrapper in twain.
I'm splitting the timer functions in EventWrapper into a separate interface.
- Users of the timer functions have different needs than users of a generic event
- Providing a default implementation for EventWrapper that simply uses rtc::Event.

This means that clients of WebRTC that don't use the relatively few classes, typically rendering classes, that depend on the event timer functionality, also don't pull in dependencies on multimedia timers.

R=mflodman@webrtc.org, mflodman
BUG=

Review URL: https://webrtc-codereview.appspot.com/48599004

Cr-Commit-Position: refs/heads/master@{#8833}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8833 4adac7df-926f-26a2-2b94-8c16560cd09d
2015-03-23 16:25:46 +00:00

394 lines
13 KiB
C++

/*
* 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 "webrtc/modules/audio_coding/main/test/iSACTest.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#if _WIN32
#include <windows.h>
#elif WEBRTC_LINUX
#include <time.h>
#else
#include <sys/time.h>
#include <time.h>
#endif
#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
#include "webrtc/modules/audio_coding/main/test/utility.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/tick_util.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/test/testsupport/fileutils.h"
namespace webrtc {
void SetISACConfigDefault(ACMTestISACConfig& isacConfig) {
isacConfig.currentRateBitPerSec = 0;
isacConfig.currentFrameSizeMsec = 0;
isacConfig.maxRateBitPerSec = 0;
isacConfig.maxPayloadSizeByte = 0;
isacConfig.encodingMode = -1;
isacConfig.initRateBitPerSec = 0;
isacConfig.initFrameSizeInMsec = 0;
isacConfig.enforceFrameSize = false;
return;
}
int16_t SetISAConfig(ACMTestISACConfig& isacConfig, AudioCodingModule* acm,
int testMode) {
if ((isacConfig.currentRateBitPerSec != 0)
|| (isacConfig.currentFrameSizeMsec != 0)) {
CodecInst sendCodec;
EXPECT_EQ(0, acm->SendCodec(&sendCodec));
if (isacConfig.currentRateBitPerSec < 0) {
// Register iSAC in adaptive (channel-dependent) mode.
sendCodec.rate = -1;
EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec));
} else {
if (isacConfig.currentRateBitPerSec != 0) {
sendCodec.rate = isacConfig.currentRateBitPerSec;
}
if (isacConfig.currentFrameSizeMsec != 0) {
sendCodec.pacsize = isacConfig.currentFrameSizeMsec
* (sendCodec.plfreq / 1000);
}
EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec));
}
}
if (isacConfig.maxRateBitPerSec > 0) {
// Set max rate.
EXPECT_EQ(0, acm->SetISACMaxRate(isacConfig.maxRateBitPerSec));
}
if (isacConfig.maxPayloadSizeByte > 0) {
// Set max payload size.
EXPECT_EQ(0, acm->SetISACMaxPayloadSize(isacConfig.maxPayloadSizeByte));
}
if ((isacConfig.initFrameSizeInMsec != 0)
|| (isacConfig.initRateBitPerSec != 0)) {
EXPECT_EQ(0, acm->ConfigISACBandwidthEstimator(
static_cast<uint8_t>(isacConfig.initFrameSizeInMsec),
static_cast<uint16_t>(isacConfig.initRateBitPerSec),
isacConfig.enforceFrameSize));
}
return 0;
}
ISACTest::ISACTest(int testMode)
: _acmA(AudioCodingModule::Create(1)),
_acmB(AudioCodingModule::Create(2)),
_testMode(testMode) {}
ISACTest::~ISACTest() {}
void ISACTest::Setup() {
int codecCntr;
CodecInst codecParam;
for (codecCntr = 0; codecCntr < AudioCodingModule::NumberOfCodecs();
codecCntr++) {
EXPECT_EQ(0, AudioCodingModule::Codec(codecCntr, &codecParam));
if (!STR_CASE_CMP(codecParam.plname, "ISAC")
&& codecParam.plfreq == 16000) {
memcpy(&_paramISAC16kHz, &codecParam, sizeof(CodecInst));
_idISAC16kHz = codecCntr;
}
if (!STR_CASE_CMP(codecParam.plname, "ISAC")
&& codecParam.plfreq == 32000) {
memcpy(&_paramISAC32kHz, &codecParam, sizeof(CodecInst));
_idISAC32kHz = codecCntr;
}
}
// Register both iSAC-wb & iSAC-swb in both sides as receiver codecs.
EXPECT_EQ(0, _acmA->RegisterReceiveCodec(_paramISAC16kHz));
EXPECT_EQ(0, _acmA->RegisterReceiveCodec(_paramISAC32kHz));
EXPECT_EQ(0, _acmB->RegisterReceiveCodec(_paramISAC16kHz));
EXPECT_EQ(0, _acmB->RegisterReceiveCodec(_paramISAC32kHz));
//--- Set A-to-B channel
_channel_A2B.reset(new Channel);
EXPECT_EQ(0, _acmA->RegisterTransportCallback(_channel_A2B.get()));
_channel_A2B->RegisterReceiverACM(_acmB.get());
//--- Set B-to-A channel
_channel_B2A.reset(new Channel);
EXPECT_EQ(0, _acmB->RegisterTransportCallback(_channel_B2A.get()));
_channel_B2A->RegisterReceiverACM(_acmA.get());
file_name_swb_ = webrtc::test::ResourcePath("audio_coding/testfile32kHz",
"pcm");
EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
_inFileA.Open(file_name_swb_, 32000, "rb");
std::string fileNameA = webrtc::test::OutputPath() + "testisac_a.pcm";
std::string fileNameB = webrtc::test::OutputPath() + "testisac_b.pcm";
_outFileA.Open(fileNameA, 32000, "wb");
_outFileB.Open(fileNameB, 32000, "wb");
while (!_inFileA.EndOfFile()) {
Run10ms();
}
CodecInst receiveCodec;
EXPECT_EQ(0, _acmA->ReceiveCodec(&receiveCodec));
EXPECT_EQ(0, _acmB->ReceiveCodec(&receiveCodec));
_inFileA.Close();
_outFileA.Close();
_outFileB.Close();
}
void ISACTest::Perform() {
Setup();
int16_t testNr = 0;
ACMTestISACConfig wbISACConfig;
ACMTestISACConfig swbISACConfig;
SetISACConfigDefault(wbISACConfig);
SetISACConfigDefault(swbISACConfig);
wbISACConfig.currentRateBitPerSec = -1;
swbISACConfig.currentRateBitPerSec = -1;
testNr++;
EncodeDecode(testNr, wbISACConfig, swbISACConfig);
if (_testMode != 0) {
SetISACConfigDefault(wbISACConfig);
SetISACConfigDefault(swbISACConfig);
wbISACConfig.currentRateBitPerSec = -1;
swbISACConfig.currentRateBitPerSec = -1;
wbISACConfig.initRateBitPerSec = 13000;
wbISACConfig.initFrameSizeInMsec = 60;
swbISACConfig.initRateBitPerSec = 20000;
swbISACConfig.initFrameSizeInMsec = 30;
testNr++;
EncodeDecode(testNr, wbISACConfig, swbISACConfig);
SetISACConfigDefault(wbISACConfig);
SetISACConfigDefault(swbISACConfig);
wbISACConfig.currentRateBitPerSec = 20000;
swbISACConfig.currentRateBitPerSec = 48000;
testNr++;
EncodeDecode(testNr, wbISACConfig, swbISACConfig);
wbISACConfig.currentRateBitPerSec = 16000;
swbISACConfig.currentRateBitPerSec = 30000;
wbISACConfig.currentFrameSizeMsec = 60;
testNr++;
EncodeDecode(testNr, wbISACConfig, swbISACConfig);
}
SetISACConfigDefault(wbISACConfig);
SetISACConfigDefault(swbISACConfig);
testNr++;
EncodeDecode(testNr, wbISACConfig, swbISACConfig);
int user_input;
if ((_testMode == 0) || (_testMode == 1)) {
swbISACConfig.maxPayloadSizeByte = static_cast<uint16_t>(200);
wbISACConfig.maxPayloadSizeByte = static_cast<uint16_t>(200);
} else {
printf("Enter the max payload-size for side A: ");
CHECK_ERROR(scanf("%d", &user_input));
swbISACConfig.maxPayloadSizeByte = (uint16_t) user_input;
printf("Enter the max payload-size for side B: ");
CHECK_ERROR(scanf("%d", &user_input));
wbISACConfig.maxPayloadSizeByte = (uint16_t) user_input;
}
testNr++;
EncodeDecode(testNr, wbISACConfig, swbISACConfig);
_acmA->ResetEncoder();
_acmB->ResetEncoder();
SetISACConfigDefault(wbISACConfig);
SetISACConfigDefault(swbISACConfig);
if ((_testMode == 0) || (_testMode == 1)) {
swbISACConfig.maxRateBitPerSec = static_cast<uint32_t>(48000);
wbISACConfig.maxRateBitPerSec = static_cast<uint32_t>(48000);
} else {
printf("Enter the max rate for side A: ");
CHECK_ERROR(scanf("%d", &user_input));
swbISACConfig.maxRateBitPerSec = (uint32_t) user_input;
printf("Enter the max rate for side B: ");
CHECK_ERROR(scanf("%d", &user_input));
wbISACConfig.maxRateBitPerSec = (uint32_t) user_input;
}
testNr++;
EncodeDecode(testNr, wbISACConfig, swbISACConfig);
testNr++;
if (_testMode == 0) {
SwitchingSamplingRate(testNr, 4);
} else {
SwitchingSamplingRate(testNr, 80);
}
}
void ISACTest::Run10ms() {
AudioFrame audioFrame;
EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
EXPECT_GE(_acmB->Add10MsData(audioFrame), 0);
EXPECT_EQ(0, _acmA->PlayoutData10Ms(32000, &audioFrame));
_outFileA.Write10MsData(audioFrame);
EXPECT_EQ(0, _acmB->PlayoutData10Ms(32000, &audioFrame));
_outFileB.Write10MsData(audioFrame);
}
void ISACTest::EncodeDecode(int testNr, ACMTestISACConfig& wbISACConfig,
ACMTestISACConfig& swbISACConfig) {
// Files in Side A and B
_inFileA.Open(file_name_swb_, 32000, "rb", true);
_inFileB.Open(file_name_swb_, 32000, "rb", true);
std::string file_name_out;
std::stringstream file_stream_a;
std::stringstream file_stream_b;
file_stream_a << webrtc::test::OutputPath();
file_stream_b << webrtc::test::OutputPath();
file_stream_a << "out_iSACTest_A_" << testNr << ".pcm";
file_stream_b << "out_iSACTest_B_" << testNr << ".pcm";
file_name_out = file_stream_a.str();
_outFileA.Open(file_name_out, 32000, "wb");
file_name_out = file_stream_b.str();
_outFileB.Open(file_name_out, 32000, "wb");
EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC16kHz));
EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC32kHz));
EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
// Side A is sending super-wideband, and side B is sending wideband.
SetISAConfig(swbISACConfig, _acmA.get(), _testMode);
SetISAConfig(wbISACConfig, _acmB.get(), _testMode);
bool adaptiveMode = false;
if ((swbISACConfig.currentRateBitPerSec == -1)
|| (wbISACConfig.currentRateBitPerSec == -1)) {
adaptiveMode = true;
}
_myTimer.Reset();
_channel_A2B->ResetStats();
_channel_B2A->ResetStats();
char currentTime[500];
CodecInst sendCodec;
EventTimerWrapper* myEvent = EventTimerWrapper::Create();
EXPECT_TRUE(myEvent->StartTimer(true, 10));
while (!(_inFileA.EndOfFile() || _inFileA.Rewinded())) {
Run10ms();
_myTimer.Tick10ms();
_myTimer.CurrentTimeHMS(currentTime);
if ((adaptiveMode) && (_testMode != 0)) {
myEvent->Wait(5000);
EXPECT_EQ(0, _acmA->SendCodec(&sendCodec));
EXPECT_EQ(0, _acmB->SendCodec(&sendCodec));
}
}
if (_testMode != 0) {
printf("\n\nSide A statistics\n\n");
_channel_A2B->PrintStats(_paramISAC32kHz);
printf("\n\nSide B statistics\n\n");
_channel_B2A->PrintStats(_paramISAC16kHz);
}
_channel_A2B->ResetStats();
_channel_B2A->ResetStats();
_outFileA.Close();
_outFileB.Close();
_inFileA.Close();
_inFileB.Close();
}
void ISACTest::SwitchingSamplingRate(int testNr, int maxSampRateChange) {
// Files in Side A
_inFileA.Open(file_name_swb_, 32000, "rb");
_inFileB.Open(file_name_swb_, 32000, "rb");
std::string file_name_out;
std::stringstream file_stream_a;
std::stringstream file_stream_b;
file_stream_a << webrtc::test::OutputPath();
file_stream_b << webrtc::test::OutputPath();
file_stream_a << "out_iSACTest_A_" << testNr << ".pcm";
file_stream_b << "out_iSACTest_B_" << testNr << ".pcm";
file_name_out = file_stream_a.str();
_outFileA.Open(file_name_out, 32000, "wb");
file_name_out = file_stream_b.str();
_outFileB.Open(file_name_out, 32000, "wb");
// Start with side A sending super-wideband and side B seding wideband.
// Toggle sending wideband/super-wideband in this test.
EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
int numSendCodecChanged = 0;
_myTimer.Reset();
char currentTime[50];
while (numSendCodecChanged < (maxSampRateChange << 1)) {
Run10ms();
_myTimer.Tick10ms();
_myTimer.CurrentTimeHMS(currentTime);
if (_testMode == 2)
printf("\r%s", currentTime);
if (_inFileA.EndOfFile()) {
if (_inFileA.SamplingFrequency() == 16000) {
// Switch side A to send super-wideband.
_inFileA.Close();
_inFileA.Open(file_name_swb_, 32000, "rb");
EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
} else {
// Switch side A to send wideband.
_inFileA.Close();
_inFileA.Open(file_name_swb_, 32000, "rb");
EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC16kHz));
}
numSendCodecChanged++;
}
if (_inFileB.EndOfFile()) {
if (_inFileB.SamplingFrequency() == 16000) {
// Switch side B to send super-wideband.
_inFileB.Close();
_inFileB.Open(file_name_swb_, 32000, "rb");
EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC32kHz));
} else {
// Switch side B to send wideband.
_inFileB.Close();
_inFileB.Open(file_name_swb_, 32000, "rb");
EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
}
numSendCodecChanged++;
}
}
_outFileA.Close();
_outFileB.Close();
_inFileA.Close();
_inFileB.Close();
}
} // namespace webrtc