summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/audio_coding/test/iSACTest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/modules/audio_coding/test/iSACTest.cc')
-rw-r--r--third_party/libwebrtc/modules/audio_coding/test/iSACTest.cc273
1 files changed, 273 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/audio_coding/test/iSACTest.cc b/third_party/libwebrtc/modules/audio_coding/test/iSACTest.cc
new file mode 100644
index 0000000000..246c485afe
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_coding/test/iSACTest.cc
@@ -0,0 +1,273 @@
+/*
+ * 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 "modules/audio_coding/test/iSACTest.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "absl/strings/match.h"
+#include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/audio_codecs/isac/audio_encoder_isac_float.h"
+#include "rtc_base/strings/string_builder.h"
+#include "rtc_base/time_utils.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+#include "test/testsupport/file_utils.h"
+
+namespace webrtc {
+
+using ::testing::AnyOf;
+using ::testing::Eq;
+using ::testing::StrCaseEq;
+
+namespace {
+
+constexpr int kISAC16kPayloadType = 103;
+constexpr int kISAC32kPayloadType = 104;
+const SdpAudioFormat kISAC16kFormat = {"ISAC", 16000, 1};
+const SdpAudioFormat kISAC32kFormat = {"ISAC", 32000, 1};
+
+AudioEncoderIsacFloat::Config TweakConfig(
+ AudioEncoderIsacFloat::Config config,
+ const ACMTestISACConfig& test_config) {
+ if (test_config.currentRateBitPerSec > 0) {
+ config.bit_rate = test_config.currentRateBitPerSec;
+ }
+ if (test_config.currentFrameSizeMsec != 0) {
+ config.frame_size_ms = test_config.currentFrameSizeMsec;
+ }
+ EXPECT_THAT(config.IsOk(), Eq(true));
+ return config;
+}
+
+void SetISACConfigDefault(ACMTestISACConfig& isacConfig) {
+ isacConfig.currentRateBitPerSec = 0;
+ isacConfig.currentFrameSizeMsec = 0;
+ isacConfig.encodingMode = -1;
+ isacConfig.initRateBitPerSec = 0;
+ isacConfig.initFrameSizeInMsec = 0;
+ isacConfig.enforceFrameSize = false;
+}
+
+} // namespace
+
+ISACTest::ISACTest()
+ : _acmA(AudioCodingModule::Create(
+ AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
+ _acmB(AudioCodingModule::Create(
+ AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))) {}
+
+ISACTest::~ISACTest() {}
+
+void ISACTest::Setup() {
+ // Register both iSAC-wb & iSAC-swb in both sides as receiver codecs.
+ std::map<int, SdpAudioFormat> receive_codecs = {
+ {kISAC16kPayloadType, kISAC16kFormat},
+ {kISAC32kPayloadType, kISAC32kFormat}};
+ _acmA->SetReceiveCodecs(receive_codecs);
+ _acmB->SetReceiveCodecs(receive_codecs);
+
+ //--- 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");
+
+ _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
+ kISAC16kPayloadType));
+ _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
+ kISAC32kPayloadType));
+
+ _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();
+ }
+
+ _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);
+
+ SetISACConfigDefault(wbISACConfig);
+ SetISACConfigDefault(swbISACConfig);
+ testNr++;
+ EncodeDecode(testNr, wbISACConfig, swbISACConfig);
+
+ testNr++;
+ SwitchingSamplingRate(testNr, 4);
+}
+
+void ISACTest::Run10ms() {
+ AudioFrame audioFrame;
+ EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
+ EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
+ EXPECT_GE(_acmB->Add10MsData(audioFrame), 0);
+ bool muted;
+ EXPECT_EQ(0, _acmA->PlayoutData10Ms(32000, &audioFrame, &muted));
+ ASSERT_FALSE(muted);
+ _outFileA.Write10MsData(audioFrame);
+ EXPECT_EQ(0, _acmB->PlayoutData10Ms(32000, &audioFrame, &muted));
+ ASSERT_FALSE(muted);
+ _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;
+ rtc::StringBuilder file_stream_a;
+ rtc::StringBuilder 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");
+
+ // Side A is sending super-wideband, and side B is sending wideband.
+ _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ TweakConfig(*AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
+ swbISACConfig),
+ kISAC32kPayloadType));
+ _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ TweakConfig(*AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
+ wbISACConfig),
+ kISAC16kPayloadType));
+
+ _channel_A2B->ResetStats();
+ _channel_B2A->ResetStats();
+
+ while (!(_inFileA.EndOfFile() || _inFileA.Rewinded())) {
+ Run10ms();
+ }
+
+ _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;
+ rtc::StringBuilder file_stream_a;
+ rtc::StringBuilder 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.
+ _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
+ kISAC32kPayloadType));
+ _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
+ kISAC16kPayloadType));
+
+ int numSendCodecChanged = 0;
+ while (numSendCodecChanged < (maxSampRateChange << 1)) {
+ Run10ms();
+ if (_inFileA.EndOfFile()) {
+ if (_inFileA.SamplingFrequency() == 16000) {
+ // Switch side A to send super-wideband.
+ _inFileA.Close();
+ _inFileA.Open(file_name_swb_, 32000, "rb");
+ _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
+ kISAC32kPayloadType));
+ } else {
+ // Switch side A to send wideband.
+ _inFileA.Close();
+ _inFileA.Open(file_name_swb_, 32000, "rb");
+ _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
+ kISAC16kPayloadType));
+ }
+ numSendCodecChanged++;
+ }
+
+ if (_inFileB.EndOfFile()) {
+ if (_inFileB.SamplingFrequency() == 16000) {
+ // Switch side B to send super-wideband.
+ _inFileB.Close();
+ _inFileB.Open(file_name_swb_, 32000, "rb");
+ _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
+ kISAC32kPayloadType));
+ } else {
+ // Switch side B to send wideband.
+ _inFileB.Close();
+ _inFileB.Open(file_name_swb_, 32000, "rb");
+ _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
+ *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
+ kISAC16kPayloadType));
+ }
+ numSendCodecChanged++;
+ }
+ }
+ _outFileA.Close();
+ _outFileB.Close();
+ _inFileA.Close();
+ _inFileB.Close();
+}
+
+} // namespace webrtc