aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/audio_coding/test/iSACTest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/modules/audio_coding/test/iSACTest.cc')
-rw-r--r--webrtc/modules/audio_coding/test/iSACTest.cc343
1 files changed, 343 insertions, 0 deletions
diff --git a/webrtc/modules/audio_coding/test/iSACTest.cc b/webrtc/modules/audio_coding/test/iSACTest.cc
new file mode 100644
index 0000000000..9f223fb81f
--- /dev/null
+++ b/webrtc/modules/audio_coding/test/iSACTest.cc
@@ -0,0 +1,343 @@
+/*
+ * 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/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/acm2/acm_common_defs.h"
+#include "webrtc/modules/audio_coding/test/utility.h"
+#include "webrtc/system_wrappers/include/event_wrapper.h"
+#include "webrtc/system_wrappers/include/tick_util.h"
+#include "webrtc/system_wrappers/include/trace.h"
+#include "webrtc/test/testsupport/fileutils.h"
+
+namespace webrtc {
+
+void SetISACConfigDefault(ACMTestISACConfig& isacConfig) {
+ isacConfig.currentRateBitPerSec = 0;
+ isacConfig.currentFrameSizeMsec = 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)) {
+ auto sendCodec = acm->SendCodec();
+ EXPECT_TRUE(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));
+ }
+ }
+
+ 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");
+ // Set test length to 500 ms (50 blocks of 10 ms each).
+ _inFileA.SetNum10MsBlocksToRead(50);
+ // Fast-forward 1 second (100 blocks) since the files start with silence.
+ _inFileA.FastForward(100);
+ 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);
+
+ 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];
+ 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_TRUE(_acmA->SendCodec());
+ EXPECT_TRUE(_acmB->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