diff options
Diffstat (limited to 'third_party/libwebrtc/modules/audio_coding/test/iSACTest.cc')
-rw-r--r-- | third_party/libwebrtc/modules/audio_coding/test/iSACTest.cc | 273 |
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 |