blob: 246c485afe62846baf0d4085ad77b878281698df [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
andrew@webrtc.org9dc45da2012-05-23 15:39:01 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_coding/test/iSACTest.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000012
niklase@google.com470e71d2011-07-07 08:21:25 +000013#include <stdio.h>
14#include <string.h>
15
Niels Möller2edab4c2018-10-22 09:48:08 +020016#include "absl/strings/match.h"
Karl Wiberg5817d3d2018-04-06 10:06:42 +020017#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Karl Wibergbf7a0462018-09-25 14:48:33 +020018#include "api/audio_codecs/isac/audio_encoder_isac_float.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020019#include "rtc_base/strings/string_builder.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "rtc_base/time_utils.h"
Karl Wibergbf7a0462018-09-25 14:48:33 +020021#include "test/gmock.h"
22#include "test/gtest.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "test/testsupport/file_utils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000024
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000025namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000026
Karl Wibergbf7a0462018-09-25 14:48:33 +020027using ::testing::AnyOf;
28using ::testing::Eq;
29using ::testing::StrCaseEq;
30
31namespace {
32
Fredrik Solenberg657b2962018-12-05 10:30:25 +010033constexpr int kISAC16kPayloadType = 103;
34constexpr int kISAC32kPayloadType = 104;
Jonas Olssona4d87372019-07-05 19:08:33 +020035const SdpAudioFormat kISAC16kFormat = {"ISAC", 16000, 1};
36const SdpAudioFormat kISAC32kFormat = {"ISAC", 32000, 1};
Karl Wibergbf7a0462018-09-25 14:48:33 +020037
38AudioEncoderIsacFloat::Config TweakConfig(
39 AudioEncoderIsacFloat::Config config,
40 const ACMTestISACConfig& test_config) {
41 if (test_config.currentRateBitPerSec > 0) {
42 config.bit_rate = test_config.currentRateBitPerSec;
43 }
44 if (test_config.currentFrameSizeMsec != 0) {
45 config.frame_size_ms = test_config.currentFrameSizeMsec;
46 }
47 EXPECT_THAT(config.IsOk(), Eq(true));
48 return config;
49}
50
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000051void SetISACConfigDefault(ACMTestISACConfig& isacConfig) {
52 isacConfig.currentRateBitPerSec = 0;
53 isacConfig.currentFrameSizeMsec = 0;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000054 isacConfig.encodingMode = -1;
55 isacConfig.initRateBitPerSec = 0;
56 isacConfig.initFrameSizeInMsec = 0;
57 isacConfig.enforceFrameSize = false;
niklase@google.com470e71d2011-07-07 08:21:25 +000058}
59
Karl Wibergbf7a0462018-09-25 14:48:33 +020060} // namespace
niklase@google.com470e71d2011-07-07 08:21:25 +000061
Fredrik Solenberg657b2962018-12-05 10:30:25 +010062ISACTest::ISACTest()
Karl Wiberg5817d3d2018-04-06 10:06:42 +020063 : _acmA(AudioCodingModule::Create(
64 AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
65 _acmB(AudioCodingModule::Create(
Fredrik Solenberg657b2962018-12-05 10:30:25 +010066 AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))) {}
niklase@google.com470e71d2011-07-07 08:21:25 +000067
turaj@webrtc.org55e17232013-10-29 04:40:09 +000068ISACTest::~ISACTest() {}
niklase@google.com470e71d2011-07-07 08:21:25 +000069
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +000070void ISACTest::Setup() {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +000071 // Register both iSAC-wb & iSAC-swb in both sides as receiver codecs.
Jonas Olssona4d87372019-07-05 19:08:33 +020072 std::map<int, SdpAudioFormat> receive_codecs = {
73 {kISAC16kPayloadType, kISAC16kFormat},
74 {kISAC32kPayloadType, kISAC32kFormat}};
Fredrik Solenberg657b2962018-12-05 10:30:25 +010075 _acmA->SetReceiveCodecs(receive_codecs);
76 _acmB->SetReceiveCodecs(receive_codecs);
niklase@google.com470e71d2011-07-07 08:21:25 +000077
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000078 //--- Set A-to-B channel
turaj@webrtc.org55e17232013-10-29 04:40:09 +000079 _channel_A2B.reset(new Channel);
80 EXPECT_EQ(0, _acmA->RegisterTransportCallback(_channel_A2B.get()));
81 _channel_A2B->RegisterReceiverACM(_acmB.get());
niklase@google.com470e71d2011-07-07 08:21:25 +000082
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000083 //--- Set B-to-A channel
turaj@webrtc.org55e17232013-10-29 04:40:09 +000084 _channel_B2A.reset(new Channel);
85 EXPECT_EQ(0, _acmB->RegisterTransportCallback(_channel_B2A.get()));
86 _channel_B2A->RegisterReceiverACM(_acmA.get());
niklase@google.com470e71d2011-07-07 08:21:25 +000087
Yves Gerey665174f2018-06-19 15:03:05 +020088 file_name_swb_ =
89 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
niklase@google.com470e71d2011-07-07 08:21:25 +000090
Jonas Olssona4d87372019-07-05 19:08:33 +020091 _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
92 *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
93 kISAC16kPayloadType));
94 _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
95 *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
96 kISAC32kPayloadType));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000097
98 _inFileA.Open(file_name_swb_, 32000, "rb");
Henrik Lundin4d682082015-12-10 16:24:39 +010099 // Set test length to 500 ms (50 blocks of 10 ms each).
100 _inFileA.SetNum10MsBlocksToRead(50);
101 // Fast-forward 1 second (100 blocks) since the files start with silence.
102 _inFileA.FastForward(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000103 std::string fileNameA = webrtc::test::OutputPath() + "testisac_a.pcm";
104 std::string fileNameB = webrtc::test::OutputPath() + "testisac_b.pcm";
105 _outFileA.Open(fileNameA, 32000, "wb");
106 _outFileB.Open(fileNameB, 32000, "wb");
107
108 while (!_inFileA.EndOfFile()) {
109 Run10ms();
110 }
Fredrik Solenberg657b2962018-12-05 10:30:25 +0100111
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000112 _inFileA.Close();
113 _outFileA.Close();
114 _outFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000115}
116
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000117void ISACTest::Perform() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000118 Setup();
niklase@google.com470e71d2011-07-07 08:21:25 +0000119
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000120 int16_t testNr = 0;
121 ACMTestISACConfig wbISACConfig;
122 ACMTestISACConfig swbISACConfig;
niklase@google.com470e71d2011-07-07 08:21:25 +0000123
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000124 SetISACConfigDefault(wbISACConfig);
125 SetISACConfigDefault(swbISACConfig);
niklase@google.com470e71d2011-07-07 08:21:25 +0000126
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000127 wbISACConfig.currentRateBitPerSec = -1;
128 swbISACConfig.currentRateBitPerSec = -1;
129 testNr++;
130 EncodeDecode(testNr, wbISACConfig, swbISACConfig);
131
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000132 SetISACConfigDefault(wbISACConfig);
133 SetISACConfigDefault(swbISACConfig);
134 testNr++;
135 EncodeDecode(testNr, wbISACConfig, swbISACConfig);
niklase@google.com470e71d2011-07-07 08:21:25 +0000136
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000137 testNr++;
Fredrik Solenberg657b2962018-12-05 10:30:25 +0100138 SwitchingSamplingRate(testNr, 4);
niklase@google.com470e71d2011-07-07 08:21:25 +0000139}
140
andresp@webrtc.orgd0b436a2014-01-13 13:15:59 +0000141void ISACTest::Run10ms() {
142 AudioFrame audioFrame;
143 EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
henrik.lundin@webrtc.orgf56c1622015-03-02 12:29:30 +0000144 EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
145 EXPECT_GE(_acmB->Add10MsData(audioFrame), 0);
henrik.lundind4ccb002016-05-17 12:21:55 -0700146 bool muted;
147 EXPECT_EQ(0, _acmA->PlayoutData10Ms(32000, &audioFrame, &muted));
148 ASSERT_FALSE(muted);
andresp@webrtc.orgd0b436a2014-01-13 13:15:59 +0000149 _outFileA.Write10MsData(audioFrame);
henrik.lundind4ccb002016-05-17 12:21:55 -0700150 EXPECT_EQ(0, _acmB->PlayoutData10Ms(32000, &audioFrame, &muted));
151 ASSERT_FALSE(muted);
andresp@webrtc.orgd0b436a2014-01-13 13:15:59 +0000152 _outFileB.Write10MsData(audioFrame);
153}
154
Yves Gerey665174f2018-06-19 15:03:05 +0200155void ISACTest::EncodeDecode(int testNr,
156 ACMTestISACConfig& wbISACConfig,
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000157 ACMTestISACConfig& swbISACConfig) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000158 // Files in Side A and B
159 _inFileA.Open(file_name_swb_, 32000, "rb", true);
160 _inFileB.Open(file_name_swb_, 32000, "rb", true);
161
162 std::string file_name_out;
Jonas Olsson366a50c2018-09-06 13:41:30 +0200163 rtc::StringBuilder file_stream_a;
164 rtc::StringBuilder file_stream_b;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000165 file_stream_a << webrtc::test::OutputPath();
166 file_stream_b << webrtc::test::OutputPath();
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000167 file_stream_a << "out_iSACTest_A_" << testNr << ".pcm";
168 file_stream_b << "out_iSACTest_B_" << testNr << ".pcm";
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000169 file_name_out = file_stream_a.str();
170 _outFileA.Open(file_name_out, 32000, "wb");
171 file_name_out = file_stream_b.str();
172 _outFileB.Open(file_name_out, 32000, "wb");
173
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000174 // Side A is sending super-wideband, and side B is sending wideband.
Jonas Olssona4d87372019-07-05 19:08:33 +0200175 _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
176 TweakConfig(*AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
177 swbISACConfig),
178 kISAC32kPayloadType));
179 _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
180 TweakConfig(*AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
181 wbISACConfig),
182 kISAC16kPayloadType));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000183
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000184 _channel_A2B->ResetStats();
185 _channel_B2A->ResetStats();
186
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000187 while (!(_inFileA.EndOfFile() || _inFileA.Rewinded())) {
188 Run10ms();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000189 }
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000190
andresp@webrtc.orgd0b436a2014-01-13 13:15:59 +0000191 _channel_A2B->ResetStats();
192 _channel_B2A->ResetStats();
193
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000194 _outFileA.Close();
195 _outFileB.Close();
196 _inFileA.Close();
197 _inFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000198}
199
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000200void ISACTest::SwitchingSamplingRate(int testNr, int maxSampRateChange) {
201 // Files in Side A
202 _inFileA.Open(file_name_swb_, 32000, "rb");
203 _inFileB.Open(file_name_swb_, 32000, "rb");
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000204
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000205 std::string file_name_out;
Jonas Olsson366a50c2018-09-06 13:41:30 +0200206 rtc::StringBuilder file_stream_a;
207 rtc::StringBuilder file_stream_b;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000208 file_stream_a << webrtc::test::OutputPath();
209 file_stream_b << webrtc::test::OutputPath();
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000210 file_stream_a << "out_iSACTest_A_" << testNr << ".pcm";
211 file_stream_b << "out_iSACTest_B_" << testNr << ".pcm";
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000212 file_name_out = file_stream_a.str();
213 _outFileA.Open(file_name_out, 32000, "wb");
214 file_name_out = file_stream_b.str();
215 _outFileB.Open(file_name_out, 32000, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000216
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000217 // Start with side A sending super-wideband and side B seding wideband.
218 // Toggle sending wideband/super-wideband in this test.
Jonas Olssona4d87372019-07-05 19:08:33 +0200219 _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
220 *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
221 kISAC32kPayloadType));
222 _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
223 *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
224 kISAC16kPayloadType));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000225
226 int numSendCodecChanged = 0;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000227 while (numSendCodecChanged < (maxSampRateChange << 1)) {
228 Run10ms();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000229 if (_inFileA.EndOfFile()) {
230 if (_inFileA.SamplingFrequency() == 16000) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000231 // Switch side A to send super-wideband.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000232 _inFileA.Close();
233 _inFileA.Open(file_name_swb_, 32000, "rb");
Jonas Olssona4d87372019-07-05 19:08:33 +0200234 _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
235 *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
236 kISAC32kPayloadType));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000237 } else {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000238 // Switch side A to send wideband.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000239 _inFileA.Close();
240 _inFileA.Open(file_name_swb_, 32000, "rb");
Jonas Olssona4d87372019-07-05 19:08:33 +0200241 _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
242 *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
243 kISAC16kPayloadType));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000244 }
245 numSendCodecChanged++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000246 }
247
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000248 if (_inFileB.EndOfFile()) {
249 if (_inFileB.SamplingFrequency() == 16000) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000250 // Switch side B to send super-wideband.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000251 _inFileB.Close();
252 _inFileB.Open(file_name_swb_, 32000, "rb");
Jonas Olssona4d87372019-07-05 19:08:33 +0200253 _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
254 *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
255 kISAC32kPayloadType));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000256 } else {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000257 // Switch side B to send wideband.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000258 _inFileB.Close();
259 _inFileB.Open(file_name_swb_, 32000, "rb");
Jonas Olssona4d87372019-07-05 19:08:33 +0200260 _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
261 *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
262 kISAC16kPayloadType));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000263 }
264 numSendCodecChanged++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000265 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000266 }
267 _outFileA.Close();
268 _outFileB.Close();
269 _inFileA.Close();
270 _inFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000271}
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +0000272
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000273} // namespace webrtc