blob: d1e1ec1e3077701a3d816b66d238b18f18730396 [file] [log] [blame]
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000011#include <assert.h>
12#include <stdlib.h>
13
Alessio Bazzicab28e57e2020-02-13 09:18:24 +010014#include <array>
kwiberg2d0c3322016-02-14 09:28:33 -080015#include <memory>
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000016#include <string>
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +000017#include <vector>
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000018
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "api/audio_codecs/opus/audio_encoder_opus.h"
20#include "modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
21#include "modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
22#include "modules/audio_coding/codecs/g722/audio_decoder_g722.h"
23#include "modules/audio_coding/codecs/g722/audio_encoder_g722.h"
24#include "modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h"
25#include "modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"
26#include "modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h"
27#include "modules/audio_coding/codecs/isac/fix/include/audio_encoder_isacfix.h"
28#include "modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h"
29#include "modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h"
30#include "modules/audio_coding/codecs/opus/audio_decoder_opus.h"
31#include "modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h"
32#include "modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h"
33#include "modules/audio_coding/neteq/tools/resample_input_audio_file.h"
34#include "test/gtest.h"
Steve Anton10542f22019-01-11 09:11:00 -080035#include "test/testsupport/file_utils.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000036
37namespace webrtc {
38
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +000039namespace {
40// The absolute difference between the input and output (the first channel) is
41// compared vs |tolerance|. The parameter |delay| is used to correct for codec
42// delays.
43void CompareInputOutput(const std::vector<int16_t>& input,
44 const std::vector<int16_t>& output,
45 size_t num_samples,
46 size_t channels,
47 int tolerance,
48 int delay) {
49 ASSERT_LE(num_samples, input.size());
50 ASSERT_LE(num_samples * channels, output.size());
51 for (unsigned int n = 0; n < num_samples - delay; ++n) {
52 ASSERT_NEAR(input[n], output[channels * n + delay], tolerance)
53 << "Exit test on first diff; n = " << n;
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +000054 }
55}
56
57// The absolute difference between the first two channels in |output| is
58// compared vs |tolerance|.
59void CompareTwoChannels(const std::vector<int16_t>& output,
60 size_t samples_per_channel,
61 size_t channels,
62 int tolerance) {
63 ASSERT_GE(channels, 2u);
64 ASSERT_LE(samples_per_channel * channels, output.size());
65 for (unsigned int n = 0; n < samples_per_channel; ++n)
66 ASSERT_NEAR(output[channels * n], output[channels * n + 1], tolerance)
67 << "Stereo samples differ.";
68}
69
70// Calculates mean-squared error between input and output (the first channel).
71// The parameter |delay| is used to correct for codec delays.
72double MseInputOutput(const std::vector<int16_t>& input,
73 const std::vector<int16_t>& output,
74 size_t num_samples,
75 size_t channels,
76 int delay) {
77 assert(delay < static_cast<int>(num_samples));
78 assert(num_samples <= input.size());
79 assert(num_samples * channels <= output.size());
80 if (num_samples == 0)
81 return 0.0;
82 double squared_sum = 0.0;
83 for (unsigned int n = 0; n < num_samples - delay; ++n) {
84 squared_sum += (input[n] - output[channels * n + delay]) *
85 (input[n] - output[channels * n + delay]);
86 }
87 return squared_sum / (num_samples - delay);
88}
89} // namespace
90
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000091class AudioDecoderTest : public ::testing::Test {
92 protected:
93 AudioDecoderTest()
kjellander02060002016-02-16 22:06:12 -080094 : input_audio_(
95 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"),
96 32000),
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +000097 codec_input_rate_hz_(32000), // Legacy default value.
henrik.lundin@webrtc.orgdef1e972014-10-21 12:48:29 +000098 frame_size_(0),
99 data_length_(0),
henrik.lundin@webrtc.orgdef1e972014-10-21 12:48:29 +0000100 channels_(1),
henrik.lundin@webrtc.org7f1dfa52014-12-02 12:08:39 +0000101 payload_type_(17),
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000102 decoder_(NULL) {}
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000103
Mirko Bonadei682aac52018-07-20 13:59:20 +0200104 ~AudioDecoderTest() override {}
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000105
Mirko Bonadei682aac52018-07-20 13:59:20 +0200106 void SetUp() override {
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000107 if (audio_encoder_)
kwiberg@webrtc.org05211272015-02-18 12:00:32 +0000108 codec_input_rate_hz_ = audio_encoder_->SampleRateHz();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000109 // Create arrays.
110 ASSERT_GT(data_length_, 0u) << "The test must set data_length_ > 0";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000111 }
112
Mirko Bonadei682aac52018-07-20 13:59:20 +0200113 void TearDown() override {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000114 delete decoder_;
115 decoder_ = NULL;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000116 }
117
Yves Gerey665174f2018-06-19 15:03:05 +0200118 virtual void InitEncoder() {}
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000119
henrik.lundin@webrtc.orgdef1e972014-10-21 12:48:29 +0000120 // TODO(henrik.lundin) Change return type to size_t once most/all overriding
121 // implementations are gone.
122 virtual int EncodeFrame(const int16_t* input,
123 size_t input_len_samples,
ossu10a029e2016-03-01 00:41:31 -0800124 rtc::Buffer* output) {
125 AudioEncoder::EncodedInfo encoded_info;
kwiberg@webrtc.org05211272015-02-18 12:00:32 +0000126 const size_t samples_per_10ms = audio_encoder_->SampleRateHz() / 100;
henrikg91d6ede2015-09-17 00:24:34 -0700127 RTC_CHECK_EQ(samples_per_10ms * audio_encoder_->Num10MsFramesInNextPacket(),
128 input_len_samples);
kwiberg2d0c3322016-02-14 09:28:33 -0800129 std::unique_ptr<int16_t[]> interleaved_input(
henrik.lundin@webrtc.org130fef82014-12-08 21:07:59 +0000130 new int16_t[channels_ * samples_per_10ms]);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700131 for (size_t i = 0; i < audio_encoder_->Num10MsFramesInNextPacket(); ++i) {
ossu10a029e2016-03-01 00:41:31 -0800132 EXPECT_EQ(0u, encoded_info.encoded_bytes);
kwiberg@webrtc.org663fdd02014-10-29 07:28:36 +0000133
134 // Duplicate the mono input signal to however many channels the test
135 // wants.
henrik.lundin@webrtc.org130fef82014-12-08 21:07:59 +0000136 test::InputAudioFile::DuplicateInterleaved(input + i * samples_per_10ms,
137 samples_per_10ms, channels_,
138 interleaved_input.get());
kwiberg@webrtc.org663fdd02014-10-29 07:28:36 +0000139
Yves Gerey665174f2018-06-19 15:03:05 +0200140 encoded_info =
141 audio_encoder_->Encode(0,
142 rtc::ArrayView<const int16_t>(
143 interleaved_input.get(),
144 audio_encoder_->NumChannels() *
145 audio_encoder_->SampleRateHz() / 100),
146 output);
henrik.lundin@webrtc.orgdef1e972014-10-21 12:48:29 +0000147 }
ossu10a029e2016-03-01 00:41:31 -0800148 EXPECT_EQ(payload_type_, encoded_info.payload_type);
149 return static_cast<int>(encoded_info.encoded_bytes);
henrik.lundin@webrtc.orgdef1e972014-10-21 12:48:29 +0000150 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000151
152 // Encodes and decodes audio. The absolute difference between the input and
153 // output is compared vs |tolerance|, and the mean-squared error is compared
minyue@webrtc.orgecbe0aa2013-08-12 06:48:09 +0000154 // with |mse|. The encoded stream should contain |expected_bytes|. For stereo
155 // audio, the absolute difference between the two channels is compared vs
156 // |channel_diff_tolerance|.
Yves Gerey665174f2018-06-19 15:03:05 +0200157 void EncodeDecodeTest(size_t expected_bytes,
158 int tolerance,
159 double mse,
160 int delay = 0,
161 int channel_diff_tolerance = 0) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000162 ASSERT_GE(tolerance, 0) << "Test must define a tolerance >= 0";
Yves Gerey665174f2018-06-19 15:03:05 +0200163 ASSERT_GE(channel_diff_tolerance, 0)
164 << "Test must define a channel_diff_tolerance >= 0";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000165 size_t processed_samples = 0u;
ossu10a029e2016-03-01 00:41:31 -0800166 size_t encoded_bytes = 0u;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000167 InitEncoder();
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000168 std::vector<int16_t> input;
169 std::vector<int16_t> decoded;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000170 while (processed_samples + frame_size_ <= data_length_) {
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000171 // Extend input vector with |frame_size_|.
172 input.resize(input.size() + frame_size_, 0);
173 // Read from input file.
174 ASSERT_GE(input.size() - processed_samples, frame_size_);
Yves Gerey665174f2018-06-19 15:03:05 +0200175 ASSERT_TRUE(input_audio_.Read(frame_size_, codec_input_rate_hz_,
176 &input[processed_samples]));
Alessio Bazzicab28e57e2020-02-13 09:18:24 +0100177 rtc::Buffer encoded;
Yves Gerey665174f2018-06-19 15:03:05 +0200178 size_t enc_len =
179 EncodeFrame(&input[processed_samples], frame_size_, &encoded);
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000180 // Make sure that frame_size_ * channels_ samples are allocated and free.
181 decoded.resize((processed_samples + frame_size_) * channels_, 0);
Alessio Bazzicab28e57e2020-02-13 09:18:24 +0100182
183 const std::vector<AudioDecoder::ParseResult> parse_result =
184 decoder_->ParsePayload(std::move(encoded), /*timestamp=*/0);
185 RTC_CHECK_EQ(parse_result.size(), size_t{1});
186 auto decode_result = parse_result[0].frame->Decode(
187 rtc::ArrayView<int16_t>(&decoded[processed_samples * channels_],
188 frame_size_ * channels_ * sizeof(int16_t)));
189 RTC_CHECK(decode_result.has_value());
190 EXPECT_EQ(frame_size_ * channels_, decode_result->num_decoded_samples);
ossu10a029e2016-03-01 00:41:31 -0800191 encoded_bytes += enc_len;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000192 processed_samples += frame_size_;
193 }
tina.legrand@webrtc.org8418e962013-11-29 09:30:43 +0000194 // For some codecs it doesn't make sense to check expected number of bytes,
195 // since the number can vary for different platforms. Opus and iSAC are
196 // such codecs. In this case expected_bytes is set to 0.
197 if (expected_bytes) {
ossu10a029e2016-03-01 00:41:31 -0800198 EXPECT_EQ(expected_bytes, encoded_bytes);
tina.legrand@webrtc.org8418e962013-11-29 09:30:43 +0000199 }
Yves Gerey665174f2018-06-19 15:03:05 +0200200 CompareInputOutput(input, decoded, processed_samples, channels_, tolerance,
201 delay);
minyue@webrtc.orgecbe0aa2013-08-12 06:48:09 +0000202 if (channels_ == 2)
Yves Gerey665174f2018-06-19 15:03:05 +0200203 CompareTwoChannels(decoded, processed_samples, channels_,
204 channel_diff_tolerance);
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000205 EXPECT_LE(
206 MseInputOutput(input, decoded, processed_samples, channels_, delay),
207 mse);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000208 }
209
210 // Encodes a payload and decodes it twice with decoder re-init before each
211 // decode. Verifies that the decoded result is the same.
212 void ReInitTest() {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000213 InitEncoder();
kwiberg2d0c3322016-02-14 09:28:33 -0800214 std::unique_ptr<int16_t[]> input(new int16_t[frame_size_]);
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000215 ASSERT_TRUE(
216 input_audio_.Read(frame_size_, codec_input_rate_hz_, input.get()));
Alessio Bazzicab28e57e2020-02-13 09:18:24 +0100217 std::array<rtc::Buffer, 2> encoded;
218 EncodeFrame(input.get(), frame_size_, &encoded[0]);
219 // Make a copy.
220 encoded[1].SetData(encoded[0].data(), encoded[0].size());
221
222 std::array<std::vector<int16_t>, 2> outputs;
223 for (size_t i = 0; i < outputs.size(); ++i) {
224 outputs[i].resize(frame_size_ * channels_);
225 decoder_->Reset();
226 const std::vector<AudioDecoder::ParseResult> parse_result =
227 decoder_->ParsePayload(std::move(encoded[i]), /*timestamp=*/0);
228 RTC_CHECK_EQ(parse_result.size(), size_t{1});
229 auto decode_result = parse_result[0].frame->Decode(outputs[i]);
230 RTC_CHECK(decode_result.has_value());
231 EXPECT_EQ(frame_size_ * channels_, decode_result->num_decoded_samples);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000232 }
Alessio Bazzicab28e57e2020-02-13 09:18:24 +0100233 EXPECT_EQ(outputs[0], outputs[1]);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000234 }
235
236 // Call DecodePlc and verify that the correct number of samples is produced.
237 void DecodePlcTest() {
238 InitEncoder();
kwiberg2d0c3322016-02-14 09:28:33 -0800239 std::unique_ptr<int16_t[]> input(new int16_t[frame_size_]);
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000240 ASSERT_TRUE(
241 input_audio_.Read(frame_size_, codec_input_rate_hz_, input.get()));
ossu10a029e2016-03-01 00:41:31 -0800242 rtc::Buffer encoded;
Alessio Bazzicab28e57e2020-02-13 09:18:24 +0100243 EncodeFrame(input.get(), frame_size_, &encoded);
Karl Wiberg43766482015-08-27 15:22:11 +0200244 decoder_->Reset();
Alessio Bazzicab28e57e2020-02-13 09:18:24 +0100245 std::vector<int16_t> output(frame_size_ * channels_);
246 const std::vector<AudioDecoder::ParseResult> parse_result =
247 decoder_->ParsePayload(std::move(encoded), /*timestamp=*/0);
248 RTC_CHECK_EQ(parse_result.size(), size_t{1});
249 auto decode_result = parse_result[0].frame->Decode(output);
250 RTC_CHECK(decode_result.has_value());
251 EXPECT_EQ(frame_size_ * channels_, decode_result->num_decoded_samples);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000252 // Call DecodePlc and verify that we get one frame of data.
253 // (Overwrite the output from the above Decode call, but that does not
254 // matter.)
Alessio Bazzicab28e57e2020-02-13 09:18:24 +0100255 size_t dec_len =
256 decoder_->DecodePlc(/*num_frames=*/1, /*decoded=*/output.data());
turaj@webrtc.org6ad6a072013-09-30 20:07:39 +0000257 EXPECT_EQ(frame_size_ * channels_, dec_len);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000258 }
259
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000260 test::ResampleInputAudioFile input_audio_;
261 int codec_input_rate_hz_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000262 size_t frame_size_;
263 size_t data_length_;
henrik.lundin@webrtc.orgaaad6132013-02-01 11:49:28 +0000264 size_t channels_;
henrik.lundin@webrtc.org7f1dfa52014-12-02 12:08:39 +0000265 const int payload_type_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000266 AudioDecoder* decoder_;
kwiberg2d0c3322016-02-14 09:28:33 -0800267 std::unique_ptr<AudioEncoder> audio_encoder_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000268};
269
270class AudioDecoderPcmUTest : public AudioDecoderTest {
271 protected:
272 AudioDecoderPcmUTest() : AudioDecoderTest() {
273 frame_size_ = 160;
274 data_length_ = 10 * frame_size_;
kwiberg89671832015-09-22 14:06:29 -0700275 decoder_ = new AudioDecoderPcmU(1);
henrik.lundin@webrtc.orgdef1e972014-10-21 12:48:29 +0000276 AudioEncoderPcmU::Config config;
277 config.frame_size_ms = static_cast<int>(frame_size_ / 8);
henrik.lundin@webrtc.org7f1dfa52014-12-02 12:08:39 +0000278 config.payload_type = payload_type_;
henrik.lundin@webrtc.orgdef1e972014-10-21 12:48:29 +0000279 audio_encoder_.reset(new AudioEncoderPcmU(config));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000280 }
281};
282
283class AudioDecoderPcmATest : public AudioDecoderTest {
284 protected:
285 AudioDecoderPcmATest() : AudioDecoderTest() {
286 frame_size_ = 160;
287 data_length_ = 10 * frame_size_;
kwiberg89671832015-09-22 14:06:29 -0700288 decoder_ = new AudioDecoderPcmA(1);
henrik.lundin@webrtc.orgdef1e972014-10-21 12:48:29 +0000289 AudioEncoderPcmA::Config config;
290 config.frame_size_ms = static_cast<int>(frame_size_ / 8);
henrik.lundin@webrtc.org7f1dfa52014-12-02 12:08:39 +0000291 config.payload_type = payload_type_;
henrik.lundin@webrtc.orgdef1e972014-10-21 12:48:29 +0000292 audio_encoder_.reset(new AudioEncoderPcmA(config));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000293 }
294};
295
296class AudioDecoderPcm16BTest : public AudioDecoderTest {
297 protected:
298 AudioDecoderPcm16BTest() : AudioDecoderTest() {
henrik.lundin@webrtc.org817e50d2014-12-11 10:47:19 +0000299 codec_input_rate_hz_ = 16000;
300 frame_size_ = 20 * codec_input_rate_hz_ / 1000;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000301 data_length_ = 10 * frame_size_;
kwiberg6c2eab32016-05-31 02:46:20 -0700302 decoder_ = new AudioDecoderPcm16B(codec_input_rate_hz_, 1);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000303 assert(decoder_);
henrik.lundin@webrtc.org817e50d2014-12-11 10:47:19 +0000304 AudioEncoderPcm16B::Config config;
305 config.sample_rate_hz = codec_input_rate_hz_;
306 config.frame_size_ms =
307 static_cast<int>(frame_size_ / (config.sample_rate_hz / 1000));
308 config.payload_type = payload_type_;
309 audio_encoder_.reset(new AudioEncoderPcm16B(config));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000310 }
311};
312
313class AudioDecoderIlbcTest : public AudioDecoderTest {
314 protected:
315 AudioDecoderIlbcTest() : AudioDecoderTest() {
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000316 codec_input_rate_hz_ = 8000;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000317 frame_size_ = 240;
318 data_length_ = 10 * frame_size_;
solenbergdb3c9b02017-06-28 02:05:04 -0700319 decoder_ = new AudioDecoderIlbcImpl;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000320 assert(decoder_);
solenbergdb3c9b02017-06-28 02:05:04 -0700321 AudioEncoderIlbcConfig config;
kwiberg@webrtc.orgcb858ba2014-12-08 17:11:44 +0000322 config.frame_size_ms = 30;
solenbergdb3c9b02017-06-28 02:05:04 -0700323 audio_encoder_.reset(new AudioEncoderIlbcImpl(config, payload_type_));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000324 }
325
326 // Overload the default test since iLBC's function WebRtcIlbcfix_NetEqPlc does
327 // not return any data. It simply resets a few states and returns 0.
328 void DecodePlcTest() {
329 InitEncoder();
kwiberg2d0c3322016-02-14 09:28:33 -0800330 std::unique_ptr<int16_t[]> input(new int16_t[frame_size_]);
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000331 ASSERT_TRUE(
332 input_audio_.Read(frame_size_, codec_input_rate_hz_, input.get()));
ossu10a029e2016-03-01 00:41:31 -0800333 rtc::Buffer encoded;
334 size_t enc_len = EncodeFrame(input.get(), frame_size_, &encoded);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000335 AudioDecoder::SpeechType speech_type;
Karl Wiberg43766482015-08-27 15:22:11 +0200336 decoder_->Reset();
kwiberg2d0c3322016-02-14 09:28:33 -0800337 std::unique_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
Yves Gerey665174f2018-06-19 15:03:05 +0200338 size_t dec_len = decoder_->Decode(
339 encoded.data(), enc_len, codec_input_rate_hz_,
340 frame_size_ * channels_ * sizeof(int16_t), output.get(), &speech_type);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000341 EXPECT_EQ(frame_size_, dec_len);
342 // Simply call DecodePlc and verify that we get 0 as return value.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700343 EXPECT_EQ(0U, decoder_->DecodePlc(1, output.get()));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000344 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000345};
346
347class AudioDecoderIsacFloatTest : public AudioDecoderTest {
348 protected:
349 AudioDecoderIsacFloatTest() : AudioDecoderTest() {
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000350 codec_input_rate_hz_ = 16000;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000351 frame_size_ = 480;
352 data_length_ = 10 * frame_size_;
kwiberg6ff045f2017-08-17 05:31:02 -0700353 AudioEncoderIsacFloatImpl::Config config;
kwiberg@webrtc.orgb3ad8cf2014-12-11 10:08:19 +0000354 config.payload_type = payload_type_;
355 config.sample_rate_hz = codec_input_rate_hz_;
356 config.frame_size_ms =
357 1000 * static_cast<int>(frame_size_) / codec_input_rate_hz_;
kwiberg6ff045f2017-08-17 05:31:02 -0700358 audio_encoder_.reset(new AudioEncoderIsacFloatImpl(config));
Jiawei Ou608e6ba2019-07-25 11:14:35 -0700359
360 AudioDecoderIsacFloatImpl::Config decoder_config;
361 decoder_config.sample_rate_hz = codec_input_rate_hz_;
362 decoder_ = new AudioDecoderIsacFloatImpl(decoder_config);
turaj@webrtc.org1431e4d2014-11-11 01:44:13 +0000363 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000364};
365
366class AudioDecoderIsacSwbTest : public AudioDecoderTest {
367 protected:
368 AudioDecoderIsacSwbTest() : AudioDecoderTest() {
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000369 codec_input_rate_hz_ = 32000;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000370 frame_size_ = 960;
371 data_length_ = 10 * frame_size_;
kwiberg6ff045f2017-08-17 05:31:02 -0700372 AudioEncoderIsacFloatImpl::Config config;
kwiberg@webrtc.orgb3ad8cf2014-12-11 10:08:19 +0000373 config.payload_type = payload_type_;
374 config.sample_rate_hz = codec_input_rate_hz_;
375 config.frame_size_ms =
376 1000 * static_cast<int>(frame_size_) / codec_input_rate_hz_;
kwiberg6ff045f2017-08-17 05:31:02 -0700377 audio_encoder_.reset(new AudioEncoderIsacFloatImpl(config));
Jiawei Ou608e6ba2019-07-25 11:14:35 -0700378
379 AudioDecoderIsacFloatImpl::Config decoder_config;
380 decoder_config.sample_rate_hz = codec_input_rate_hz_;
381 decoder_ = new AudioDecoderIsacFloatImpl(decoder_config);
turaj@webrtc.org1431e4d2014-11-11 01:44:13 +0000382 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000383};
384
385class AudioDecoderIsacFixTest : public AudioDecoderTest {
386 protected:
387 AudioDecoderIsacFixTest() : AudioDecoderTest() {
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000388 codec_input_rate_hz_ = 16000;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000389 frame_size_ = 480;
390 data_length_ = 10 * frame_size_;
kwiberg6ff045f2017-08-17 05:31:02 -0700391 AudioEncoderIsacFixImpl::Config config;
kwiberg@webrtc.org88bdec82014-12-16 12:49:37 +0000392 config.payload_type = payload_type_;
393 config.sample_rate_hz = codec_input_rate_hz_;
394 config.frame_size_ms =
395 1000 * static_cast<int>(frame_size_) / codec_input_rate_hz_;
kwiberg6ff045f2017-08-17 05:31:02 -0700396 audio_encoder_.reset(new AudioEncoderIsacFixImpl(config));
Jiawei Ou608e6ba2019-07-25 11:14:35 -0700397
398 AudioDecoderIsacFixImpl::Config decoder_config;
399 decoder_config.sample_rate_hz = codec_input_rate_hz_;
400 decoder_ = new AudioDecoderIsacFixImpl(decoder_config);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000401 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000402};
403
404class AudioDecoderG722Test : public AudioDecoderTest {
405 protected:
406 AudioDecoderG722Test() : AudioDecoderTest() {
henrik.lundin@webrtc.orga37f1dd2014-10-27 12:58:18 +0000407 codec_input_rate_hz_ = 16000;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000408 frame_size_ = 160;
409 data_length_ = 10 * frame_size_;
kwibergb1ed7f02017-06-17 17:30:09 -0700410 decoder_ = new AudioDecoderG722Impl;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000411 assert(decoder_);
kwibergb8727ae2017-06-17 17:41:59 -0700412 AudioEncoderG722Config config;
kwiberg@webrtc.org0cd55582014-12-02 11:45:51 +0000413 config.frame_size_ms = 10;
414 config.num_channels = 1;
kwibergb8727ae2017-06-17 17:41:59 -0700415 audio_encoder_.reset(new AudioEncoderG722Impl(config, payload_type_));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000416 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000417};
418
kwiberg@webrtc.org0cd55582014-12-02 11:45:51 +0000419class AudioDecoderG722StereoTest : public AudioDecoderTest {
henrik.lundin@webrtc.orgaaad6132013-02-01 11:49:28 +0000420 protected:
kwiberg@webrtc.org0cd55582014-12-02 11:45:51 +0000421 AudioDecoderG722StereoTest() : AudioDecoderTest() {
henrik.lundin@webrtc.orgaaad6132013-02-01 11:49:28 +0000422 channels_ = 2;
kwiberg@webrtc.org0cd55582014-12-02 11:45:51 +0000423 codec_input_rate_hz_ = 16000;
424 frame_size_ = 160;
425 data_length_ = 10 * frame_size_;
kwiberg1b97e262017-06-26 04:19:43 -0700426 decoder_ = new AudioDecoderG722StereoImpl;
henrik.lundin@webrtc.orgaaad6132013-02-01 11:49:28 +0000427 assert(decoder_);
kwibergb8727ae2017-06-17 17:41:59 -0700428 AudioEncoderG722Config config;
kwiberg@webrtc.org0cd55582014-12-02 11:45:51 +0000429 config.frame_size_ms = 10;
430 config.num_channels = 2;
kwibergb8727ae2017-06-17 17:41:59 -0700431 audio_encoder_.reset(new AudioEncoderG722Impl(config, payload_type_));
henrik.lundin@webrtc.orgaaad6132013-02-01 11:49:28 +0000432 }
433};
434
Karl Wiberg7eb0a5e2019-05-29 13:46:09 +0200435class AudioDecoderOpusTest
436 : public AudioDecoderTest,
437 public testing::WithParamInterface<std::tuple<int, int>> {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000438 protected:
439 AudioDecoderOpusTest() : AudioDecoderTest() {
Karl Wiberg7eb0a5e2019-05-29 13:46:09 +0200440 channels_ = opus_num_channels_;
441 codec_input_rate_hz_ = opus_sample_rate_hz_;
442 frame_size_ = rtc::CheckedDivExact(opus_sample_rate_hz_, 100);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000443 data_length_ = 10 * frame_size_;
Karl Wiberg7eb0a5e2019-05-29 13:46:09 +0200444 decoder_ =
445 new AudioDecoderOpusImpl(opus_num_channels_, opus_sample_rate_hz_);
kwiberg96da0112017-06-30 04:23:22 -0700446 AudioEncoderOpusConfig config;
Karl Wiberg7eb0a5e2019-05-29 13:46:09 +0200447 config.frame_size_ms = 10;
448 config.sample_rate_hz = opus_sample_rate_hz_;
449 config.num_channels = opus_num_channels_;
450 config.application = opus_num_channels_ == 1
451 ? AudioEncoderOpusConfig::ApplicationMode::kVoip
452 : AudioEncoderOpusConfig::ApplicationMode::kAudio;
kwiberg96da0112017-06-30 04:23:22 -0700453 audio_encoder_ = AudioEncoderOpus::MakeAudioEncoder(config, payload_type_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000454 }
Karl Wiberg7eb0a5e2019-05-29 13:46:09 +0200455 const int opus_sample_rate_hz_{std::get<0>(GetParam())};
456 const int opus_num_channels_{std::get<1>(GetParam())};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000457};
458
Karl Wiberg7eb0a5e2019-05-29 13:46:09 +0200459INSTANTIATE_TEST_SUITE_P(Param,
460 AudioDecoderOpusTest,
461 testing::Combine(testing::Values(16000, 48000),
462 testing::Values(1, 2)));
minyue@webrtc.orgecbe0aa2013-08-12 06:48:09 +0000463
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000464TEST_F(AudioDecoderPcmUTest, EncodeDecode) {
465 int tolerance = 251;
466 double mse = 1734.0;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000467 EncodeDecodeTest(data_length_, tolerance, mse);
468 ReInitTest();
469 EXPECT_FALSE(decoder_->HasDecodePlc());
470}
471
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200472namespace {
473int SetAndGetTargetBitrate(AudioEncoder* audio_encoder, int rate) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200474 audio_encoder->OnReceivedUplinkBandwidth(rate, absl::nullopt);
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200475 return audio_encoder->GetTargetBitrate();
476}
477void TestSetAndGetTargetBitratesWithFixedCodec(AudioEncoder* audio_encoder,
478 int fixed_rate) {
479 EXPECT_EQ(fixed_rate, SetAndGetTargetBitrate(audio_encoder, 32000));
480 EXPECT_EQ(fixed_rate, SetAndGetTargetBitrate(audio_encoder, fixed_rate - 1));
481 EXPECT_EQ(fixed_rate, SetAndGetTargetBitrate(audio_encoder, fixed_rate));
482 EXPECT_EQ(fixed_rate, SetAndGetTargetBitrate(audio_encoder, fixed_rate + 1));
483}
484} // namespace
485
486TEST_F(AudioDecoderPcmUTest, SetTargetBitrate) {
487 TestSetAndGetTargetBitratesWithFixedCodec(audio_encoder_.get(), 64000);
488}
489
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000490TEST_F(AudioDecoderPcmATest, EncodeDecode) {
491 int tolerance = 308;
492 double mse = 1931.0;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000493 EncodeDecodeTest(data_length_, tolerance, mse);
494 ReInitTest();
495 EXPECT_FALSE(decoder_->HasDecodePlc());
496}
497
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200498TEST_F(AudioDecoderPcmATest, SetTargetBitrate) {
499 TestSetAndGetTargetBitratesWithFixedCodec(audio_encoder_.get(), 64000);
500}
501
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000502TEST_F(AudioDecoderPcm16BTest, EncodeDecode) {
503 int tolerance = 0;
504 double mse = 0.0;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000505 EncodeDecodeTest(2 * data_length_, tolerance, mse);
506 ReInitTest();
507 EXPECT_FALSE(decoder_->HasDecodePlc());
508}
509
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200510TEST_F(AudioDecoderPcm16BTest, SetTargetBitrate) {
511 TestSetAndGetTargetBitratesWithFixedCodec(audio_encoder_.get(),
512 codec_input_rate_hz_ * 16);
513}
514
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000515TEST_F(AudioDecoderIlbcTest, EncodeDecode) {
516 int tolerance = 6808;
517 double mse = 2.13e6;
518 int delay = 80; // Delay from input to output.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000519 EncodeDecodeTest(500, tolerance, mse, delay);
520 ReInitTest();
521 EXPECT_TRUE(decoder_->HasDecodePlc());
522 DecodePlcTest();
523}
524
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200525TEST_F(AudioDecoderIlbcTest, SetTargetBitrate) {
526 TestSetAndGetTargetBitratesWithFixedCodec(audio_encoder_.get(), 13333);
527}
528
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000529TEST_F(AudioDecoderIsacFloatTest, EncodeDecode) {
530 int tolerance = 3399;
531 double mse = 434951.0;
532 int delay = 48; // Delay from input to output.
tina.legrand@webrtc.org8418e962013-11-29 09:30:43 +0000533 EncodeDecodeTest(0, tolerance, mse, delay);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000534 ReInitTest();
henrik.lundin@webrtc.org09b6ff92015-03-23 12:23:51 +0000535 EXPECT_FALSE(decoder_->HasDecodePlc());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000536}
537
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200538TEST_F(AudioDecoderIsacFloatTest, SetTargetBitrate) {
Björn Tereliusd5461862020-10-27 10:51:34 +0000539 EXPECT_EQ(10000, SetAndGetTargetBitrate(audio_encoder_.get(), 9999));
540 EXPECT_EQ(10000, SetAndGetTargetBitrate(audio_encoder_.get(), 10000));
541 EXPECT_EQ(23456, SetAndGetTargetBitrate(audio_encoder_.get(), 23456));
542 EXPECT_EQ(32000, SetAndGetTargetBitrate(audio_encoder_.get(), 32000));
543 EXPECT_EQ(32000, SetAndGetTargetBitrate(audio_encoder_.get(), 32001));
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200544}
545
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000546TEST_F(AudioDecoderIsacSwbTest, EncodeDecode) {
547 int tolerance = 19757;
548 double mse = 8.18e6;
549 int delay = 160; // Delay from input to output.
tina.legrand@webrtc.org8418e962013-11-29 09:30:43 +0000550 EncodeDecodeTest(0, tolerance, mse, delay);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000551 ReInitTest();
henrik.lundin@webrtc.org09b6ff92015-03-23 12:23:51 +0000552 EXPECT_FALSE(decoder_->HasDecodePlc());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000553}
554
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200555TEST_F(AudioDecoderIsacSwbTest, SetTargetBitrate) {
Björn Tereliusd5461862020-10-27 10:51:34 +0000556 EXPECT_EQ(10000, SetAndGetTargetBitrate(audio_encoder_.get(), 9999));
557 EXPECT_EQ(10000, SetAndGetTargetBitrate(audio_encoder_.get(), 10000));
558 EXPECT_EQ(23456, SetAndGetTargetBitrate(audio_encoder_.get(), 23456));
559 EXPECT_EQ(56000, SetAndGetTargetBitrate(audio_encoder_.get(), 56000));
560 EXPECT_EQ(56000, SetAndGetTargetBitrate(audio_encoder_.get(), 56001));
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200561}
562
kwiberg5b659c02015-12-11 07:33:59 -0800563TEST_F(AudioDecoderIsacFixTest, EncodeDecode) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000564 int tolerance = 11034;
565 double mse = 3.46e6;
566 int delay = 54; // Delay from input to output.
kwiberg5b659c02015-12-11 07:33:59 -0800567#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM)
kwiberg@webrtc.orge102e812014-12-17 07:30:23 +0000568 static const int kEncodedBytes = 685;
kwiberg5b659c02015-12-11 07:33:59 -0800569#elif defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64)
570 static const int kEncodedBytes = 673;
kwiberg@webrtc.orge102e812014-12-17 07:30:23 +0000571#else
572 static const int kEncodedBytes = 671;
573#endif
574 EncodeDecodeTest(kEncodedBytes, tolerance, mse, delay);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000575 ReInitTest();
henrik.lundin@webrtc.org09b6ff92015-03-23 12:23:51 +0000576 EXPECT_FALSE(decoder_->HasDecodePlc());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000577}
578
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200579TEST_F(AudioDecoderIsacFixTest, SetTargetBitrate) {
Björn Tereliusd5461862020-10-27 10:51:34 +0000580 EXPECT_EQ(10000, SetAndGetTargetBitrate(audio_encoder_.get(), 9999));
581 EXPECT_EQ(10000, SetAndGetTargetBitrate(audio_encoder_.get(), 10000));
582 EXPECT_EQ(23456, SetAndGetTargetBitrate(audio_encoder_.get(), 23456));
583 EXPECT_EQ(32000, SetAndGetTargetBitrate(audio_encoder_.get(), 32000));
584 EXPECT_EQ(32000, SetAndGetTargetBitrate(audio_encoder_.get(), 32001));
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200585}
586
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000587TEST_F(AudioDecoderG722Test, EncodeDecode) {
588 int tolerance = 6176;
589 double mse = 238630.0;
590 int delay = 22; // Delay from input to output.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000591 EncodeDecodeTest(data_length_ / 2, tolerance, mse, delay);
592 ReInitTest();
593 EXPECT_FALSE(decoder_->HasDecodePlc());
594}
595
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200596TEST_F(AudioDecoderG722Test, SetTargetBitrate) {
597 TestSetAndGetTargetBitratesWithFixedCodec(audio_encoder_.get(), 64000);
598}
599
henrik.lundin@webrtc.orgaaad6132013-02-01 11:49:28 +0000600TEST_F(AudioDecoderG722StereoTest, EncodeDecode) {
601 int tolerance = 6176;
minyue@webrtc.orgecbe0aa2013-08-12 06:48:09 +0000602 int channel_diff_tolerance = 0;
henrik.lundin@webrtc.orgaaad6132013-02-01 11:49:28 +0000603 double mse = 238630.0;
604 int delay = 22; // Delay from input to output.
minyue@webrtc.orgecbe0aa2013-08-12 06:48:09 +0000605 EncodeDecodeTest(data_length_, tolerance, mse, delay, channel_diff_tolerance);
henrik.lundin@webrtc.orgaaad6132013-02-01 11:49:28 +0000606 ReInitTest();
607 EXPECT_FALSE(decoder_->HasDecodePlc());
608}
609
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200610TEST_F(AudioDecoderG722StereoTest, SetTargetBitrate) {
611 TestSetAndGetTargetBitratesWithFixedCodec(audio_encoder_.get(), 128000);
612}
613
Ivo Creusen16ddae92020-03-04 17:16:59 +0100614TEST_P(AudioDecoderOpusTest, EncodeDecode) {
Karl Wiberg7eb0a5e2019-05-29 13:46:09 +0200615 constexpr int tolerance = 6176;
Ivo Creusen16ddae92020-03-04 17:16:59 +0100616 constexpr int channel_diff_tolerance = 6;
Karl Wiberg7eb0a5e2019-05-29 13:46:09 +0200617 constexpr double mse = 238630.0;
618 constexpr int delay = 22; // Delay from input to output.
tina.legrand@webrtc.org8418e962013-11-29 09:30:43 +0000619 EncodeDecodeTest(0, tolerance, mse, delay, channel_diff_tolerance);
minyue@webrtc.orgecbe0aa2013-08-12 06:48:09 +0000620 ReInitTest();
621 EXPECT_FALSE(decoder_->HasDecodePlc());
622}
623
Karl Wiberg7eb0a5e2019-05-29 13:46:09 +0200624TEST_P(AudioDecoderOpusTest, SetTargetBitrate) {
Björn Tereliusd5461862020-10-27 10:51:34 +0000625 EXPECT_EQ(6000, SetAndGetTargetBitrate(audio_encoder_.get(), 5999));
626 EXPECT_EQ(6000, SetAndGetTargetBitrate(audio_encoder_.get(), 6000));
627 EXPECT_EQ(32000, SetAndGetTargetBitrate(audio_encoder_.get(), 32000));
628 EXPECT_EQ(510000, SetAndGetTargetBitrate(audio_encoder_.get(), 510000));
629 EXPECT_EQ(510000, SetAndGetTargetBitrate(audio_encoder_.get(), 511000));
Henrik Lundin3e89dbf2015-06-18 14:58:34 +0200630}
631
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000632} // namespace webrtc