blob: 9f2c1bbe72b05fe83d902bbf5348abf952f118e4 [file] [log] [blame]
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +00001/*
2 * Copyright (c) 2013 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 */
kwiberg91d97562016-02-14 01:10:03 -080010
11#include <memory>
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000012#include <string>
13
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "modules/audio_coding/codecs/opus/opus_inst.h"
15#include "modules/audio_coding/codecs/opus/opus_interface.h"
16#include "modules/audio_coding/neteq/tools/audio_loop.h"
17#include "rtc_base/checks.h"
18#include "test/gtest.h"
19#include "test/testsupport/fileutils.h"
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000020
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000021namespace webrtc {
22
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000023using test::AudioLoop;
minyue@webrtc.org7dba7862015-01-20 16:01:50 +000024using ::testing::TestWithParam;
25using ::testing::Values;
26using ::testing::Combine;
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000027
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000028// Maximum number of bytes in output bitstream.
pbos@webrtc.org3004c792013-05-07 12:36:21 +000029const size_t kMaxBytes = 1000;
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000030// Sample rate of Opus.
Peter Kastingdce40cf2015-08-24 14:52:23 -070031const size_t kOpusRateKhz = 48;
minyue@webrtc.orgf563e852014-07-18 21:11:27 +000032// Number of samples-per-channel in a 20 ms frame, sampled at 48 kHz.
Peter Kastingdce40cf2015-08-24 14:52:23 -070033const size_t kOpus20msFrameSamples = kOpusRateKhz * 20;
minyue@webrtc.orgf563e852014-07-18 21:11:27 +000034// Number of samples-per-channel in a 10 ms frame, sampled at 48 kHz.
Peter Kastingdce40cf2015-08-24 14:52:23 -070035const size_t kOpus10msFrameSamples = kOpusRateKhz * 10;
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000036
minyue@webrtc.org7dba7862015-01-20 16:01:50 +000037class OpusTest : public TestWithParam<::testing::tuple<int, int>> {
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000038 protected:
39 OpusTest();
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000040
minyue3cea2562015-11-10 03:49:26 -080041 void TestDtxEffect(bool dtx, int block_length_ms);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000042
soren28dc2852017-04-06 05:48:36 -070043 void TestCbrEffect(bool dtx, int block_length_ms);
44
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000045 // Prepare |speech_data_| for encoding, read from a hard-coded file.
46 // After preparation, |speech_data_.GetNextBlock()| returns a pointer to a
47 // block of |block_length_ms| milliseconds. The data is looped every
48 // |loop_length_ms| milliseconds.
Peter Kasting69558702016-01-12 16:26:35 -080049 void PrepareSpeechData(size_t channel,
50 int block_length_ms,
51 int loop_length_ms);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000052
53 int EncodeDecode(WebRtcOpusEncInst* encoder,
kwiberg288886b2015-11-06 01:21:35 -080054 rtc::ArrayView<const int16_t> input_audio,
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000055 WebRtcOpusDecInst* decoder,
56 int16_t* output_audio,
57 int16_t* audio_type);
minyue@webrtc.org0040a6e2014-08-04 14:41:57 +000058
minyue@webrtc.org7dba7862015-01-20 16:01:50 +000059 void SetMaxPlaybackRate(WebRtcOpusEncInst* encoder,
60 opus_int32 expect, int32_t set);
61
Peter Kasting69558702016-01-12 16:26:35 -080062 void CheckAudioBounded(const int16_t* audio, size_t samples, size_t channels,
minyue3cea2562015-11-10 03:49:26 -080063 uint16_t bound) const;
64
minyue@webrtc.org7dba7862015-01-20 16:01:50 +000065 WebRtcOpusEncInst* opus_encoder_;
66 WebRtcOpusDecInst* opus_decoder_;
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000067
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000068 AudioLoop speech_data_;
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000069 uint8_t bitstream_[kMaxBytes];
Peter Kastingdce40cf2015-08-24 14:52:23 -070070 size_t encoded_bytes_;
Peter Kasting69558702016-01-12 16:26:35 -080071 size_t channels_;
minyue@webrtc.org7dba7862015-01-20 16:01:50 +000072 int application_;
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000073};
74
75OpusTest::OpusTest()
minyue@webrtc.org7dba7862015-01-20 16:01:50 +000076 : opus_encoder_(NULL),
77 opus_decoder_(NULL),
78 encoded_bytes_(0),
Peter Kasting69558702016-01-12 16:26:35 -080079 channels_(static_cast<size_t>(::testing::get<0>(GetParam()))),
minyue@webrtc.org7dba7862015-01-20 16:01:50 +000080 application_(::testing::get<1>(GetParam())) {
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000081}
82
Peter Kasting69558702016-01-12 16:26:35 -080083void OpusTest::PrepareSpeechData(size_t channel, int block_length_ms,
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000084 int loop_length_ms) {
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000085 const std::string file_name =
minyue@webrtc.org7dba7862015-01-20 16:01:50 +000086 webrtc::test::ResourcePath((channel == 1) ?
87 "audio_coding/testfile32kHz" :
88 "audio_coding/teststereo32kHz", "pcm");
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +000089 if (loop_length_ms < block_length_ms) {
90 loop_length_ms = block_length_ms;
91 }
92 EXPECT_TRUE(speech_data_.Init(file_name,
93 loop_length_ms * kOpusRateKhz * channel,
94 block_length_ms * kOpusRateKhz * channel));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +000095}
96
minyue@webrtc.org7dba7862015-01-20 16:01:50 +000097void OpusTest::SetMaxPlaybackRate(WebRtcOpusEncInst* encoder,
98 opus_int32 expect,
99 int32_t set) {
minyue@webrtc.org0040a6e2014-08-04 14:41:57 +0000100 opus_int32 bandwidth;
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000101 EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, set));
102 opus_encoder_ctl(opus_encoder_->encoder,
minyue@webrtc.org0040a6e2014-08-04 14:41:57 +0000103 OPUS_GET_MAX_BANDWIDTH(&bandwidth));
104 EXPECT_EQ(expect, bandwidth);
105}
106
minyue3cea2562015-11-10 03:49:26 -0800107void OpusTest::CheckAudioBounded(const int16_t* audio, size_t samples,
Peter Kasting69558702016-01-12 16:26:35 -0800108 size_t channels, uint16_t bound) const {
minyue3cea2562015-11-10 03:49:26 -0800109 for (size_t i = 0; i < samples; ++i) {
Peter Kasting69558702016-01-12 16:26:35 -0800110 for (size_t c = 0; c < channels; ++c) {
minyue3cea2562015-11-10 03:49:26 -0800111 ASSERT_GE(audio[i * channels + c], -bound);
112 ASSERT_LE(audio[i * channels + c], bound);
113 }
114 }
115}
116
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000117int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder,
kwiberg288886b2015-11-06 01:21:35 -0800118 rtc::ArrayView<const int16_t> input_audio,
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000119 WebRtcOpusDecInst* decoder,
120 int16_t* output_audio,
121 int16_t* audio_type) {
kwiberg288886b2015-11-06 01:21:35 -0800122 int encoded_bytes_int = WebRtcOpus_Encode(
123 encoder, input_audio.data(),
Peter Kasting69558702016-01-12 16:26:35 -0800124 rtc::CheckedDivExact(input_audio.size(), channels_),
kwiberg288886b2015-11-06 01:21:35 -0800125 kMaxBytes, bitstream_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700126 EXPECT_GE(encoded_bytes_int, 0);
127 encoded_bytes_ = static_cast<size_t>(encoded_bytes_int);
minyuel6d92bf52015-09-23 15:20:39 +0200128 int est_len = WebRtcOpus_DurationEst(decoder, bitstream_, encoded_bytes_);
129 int act_len = WebRtcOpus_Decode(decoder, bitstream_,
130 encoded_bytes_, output_audio,
131 audio_type);
132 EXPECT_EQ(est_len, act_len);
133 return act_len;
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000134}
135
136// Test if encoder/decoder can enter DTX mode properly and do not enter DTX when
137// they should not. This test is signal dependent.
minyue3cea2562015-11-10 03:49:26 -0800138void OpusTest::TestDtxEffect(bool dtx, int block_length_ms) {
139 PrepareSpeechData(channels_, block_length_ms, 2000);
140 const size_t samples = kOpusRateKhz * block_length_ms;
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000141
142 // Create encoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000143 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
144 channels_,
145 application_));
146 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000147
148 // Set bitrate.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000149 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_,
150 channels_ == 1 ? 32000 : 64000));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000151
152 // Set input audio as silence.
minyue3cea2562015-11-10 03:49:26 -0800153 std::vector<int16_t> silence(samples * channels_, 0);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000154
155 // Setting DTX.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000156 EXPECT_EQ(0, dtx ? WebRtcOpus_EnableDtx(opus_encoder_) :
157 WebRtcOpus_DisableDtx(opus_encoder_));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000158
159 int16_t audio_type;
minyue3cea2562015-11-10 03:49:26 -0800160 int16_t* output_data_decode = new int16_t[samples * channels_];
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000161
162 for (int i = 0; i < 100; ++i) {
minyue3cea2562015-11-10 03:49:26 -0800163 EXPECT_EQ(samples,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700164 static_cast<size_t>(EncodeDecode(
kwiberg288886b2015-11-06 01:21:35 -0800165 opus_encoder_, speech_data_.GetNextBlock(), opus_decoder_,
166 output_data_decode, &audio_type)));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000167 // If not DTX, it should never enter DTX mode. If DTX, we do not care since
168 // whether it enters DTX depends on the signal type.
169 if (!dtx) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700170 EXPECT_GT(encoded_bytes_, 1U);
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000171 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
172 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000173 EXPECT_EQ(0, audio_type); // Speech.
174 }
175 }
176
177 // We input some silent segments. In DTX mode, the encoder will stop sending.
178 // However, DTX may happen after a while.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000179 for (int i = 0; i < 30; ++i) {
minyue3cea2562015-11-10 03:49:26 -0800180 EXPECT_EQ(samples,
181 static_cast<size_t>(EncodeDecode(
182 opus_encoder_, silence, opus_decoder_, output_data_decode,
183 &audio_type)));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000184 if (!dtx) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700185 EXPECT_GT(encoded_bytes_, 1U);
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000186 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
187 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000188 EXPECT_EQ(0, audio_type); // Speech.
Peter Kasting728d9032015-06-11 14:31:38 -0700189 } else if (encoded_bytes_ == 1) {
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000190 EXPECT_EQ(1, opus_encoder_->in_dtx_mode);
191 EXPECT_EQ(1, opus_decoder_->in_dtx_mode);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000192 EXPECT_EQ(2, audio_type); // Comfort noise.
193 break;
194 }
195 }
196
Minyue Li092041c2015-05-11 12:19:35 +0200197 // When Opus is in DTX, it wakes up in a regular basis. It sends two packets,
198 // one with an arbitrary size and the other of 1-byte, then stops sending for
minyue3cea2562015-11-10 03:49:26 -0800199 // a certain number of frames.
200
201 // |max_dtx_frames| is the maximum number of frames Opus can stay in DTX.
202 const int max_dtx_frames = 400 / block_length_ms + 1;
203
204 // We run |kRunTimeMs| milliseconds of pure silence.
minyue58e08cb2016-02-24 03:49:19 -0800205 const int kRunTimeMs = 4500;
minyue3cea2562015-11-10 03:49:26 -0800206
207 // We check that, after a |kCheckTimeMs| milliseconds (given that the CNG in
208 // Opus needs time to adapt), the absolute values of DTX decoded signal are
209 // bounded by |kOutputValueBound|.
minyue58e08cb2016-02-24 03:49:19 -0800210 const int kCheckTimeMs = 4000;
minyue3cea2562015-11-10 03:49:26 -0800211
212#if defined(OPUS_FIXED_POINT)
minyuel7e937e92016-02-29 10:24:15 +0100213 // Fixed-point Opus generates a random (comfort) noise, which has a less
214 // predictable value bound than its floating-point Opus. This value depends on
215 // input signal, and the time window for checking the output values (between
216 // |kCheckTimeMs| and |kRunTimeMs|).
217 const uint16_t kOutputValueBound = 30;
218
minyue3cea2562015-11-10 03:49:26 -0800219#else
minyue58e08cb2016-02-24 03:49:19 -0800220 const uint16_t kOutputValueBound = 2;
minyue3cea2562015-11-10 03:49:26 -0800221#endif
222
223 int time = 0;
224 while (time < kRunTimeMs) {
225 // DTX mode is maintained for maximum |max_dtx_frames| frames.
226 int i = 0;
227 for (; i < max_dtx_frames; ++i) {
228 time += block_length_ms;
229 EXPECT_EQ(samples,
230 static_cast<size_t>(EncodeDecode(
231 opus_encoder_, silence, opus_decoder_, output_data_decode,
232 &audio_type)));
Minyue Li092041c2015-05-11 12:19:35 +0200233 if (dtx) {
minyue3cea2562015-11-10 03:49:26 -0800234 if (encoded_bytes_ > 1)
235 break;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700236 EXPECT_EQ(0U, encoded_bytes_) // Send 0 byte.
Minyue Li092041c2015-05-11 12:19:35 +0200237 << "Opus should have entered DTX mode.";
238 EXPECT_EQ(1, opus_encoder_->in_dtx_mode);
239 EXPECT_EQ(1, opus_decoder_->in_dtx_mode);
240 EXPECT_EQ(2, audio_type); // Comfort noise.
minyue3cea2562015-11-10 03:49:26 -0800241 if (time >= kCheckTimeMs) {
242 CheckAudioBounded(output_data_decode, samples, channels_,
243 kOutputValueBound);
244 }
Minyue Li092041c2015-05-11 12:19:35 +0200245 } else {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700246 EXPECT_GT(encoded_bytes_, 1U);
Minyue Li092041c2015-05-11 12:19:35 +0200247 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
248 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
249 EXPECT_EQ(0, audio_type); // Speech.
250 }
251 }
252
minyue3cea2562015-11-10 03:49:26 -0800253 if (dtx) {
254 // With DTX, Opus must stop transmission for some time.
255 EXPECT_GT(i, 1);
256 }
Minyue Li092041c2015-05-11 12:19:35 +0200257
minyue3cea2562015-11-10 03:49:26 -0800258 // We expect a normal payload.
Minyue Li092041c2015-05-11 12:19:35 +0200259 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
260 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
261 EXPECT_EQ(0, audio_type); // Speech.
262
263 // Enters DTX again immediately.
minyue3cea2562015-11-10 03:49:26 -0800264 time += block_length_ms;
265 EXPECT_EQ(samples,
266 static_cast<size_t>(EncodeDecode(
267 opus_encoder_, silence, opus_decoder_, output_data_decode,
268 &audio_type)));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000269 if (dtx) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700270 EXPECT_EQ(1U, encoded_bytes_); // Send 1 byte.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000271 EXPECT_EQ(1, opus_encoder_->in_dtx_mode);
272 EXPECT_EQ(1, opus_decoder_->in_dtx_mode);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000273 EXPECT_EQ(2, audio_type); // Comfort noise.
minyue3cea2562015-11-10 03:49:26 -0800274 if (time >= kCheckTimeMs) {
275 CheckAudioBounded(output_data_decode, samples, channels_,
276 kOutputValueBound);
277 }
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000278 } else {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700279 EXPECT_GT(encoded_bytes_, 1U);
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000280 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
281 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000282 EXPECT_EQ(0, audio_type); // Speech.
283 }
284 }
285
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000286 silence[0] = 10000;
287 if (dtx) {
288 // Verify that encoder/decoder can jump out from DTX mode.
minyue3cea2562015-11-10 03:49:26 -0800289 EXPECT_EQ(samples,
290 static_cast<size_t>(EncodeDecode(
291 opus_encoder_, silence, opus_decoder_, output_data_decode,
292 &audio_type)));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700293 EXPECT_GT(encoded_bytes_, 1U);
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000294 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
295 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000296 EXPECT_EQ(0, audio_type); // Speech.
297 }
298
299 // Free memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000300 delete[] output_data_decode;
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000301 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
302 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000303}
304
soren28dc2852017-04-06 05:48:36 -0700305// Test if CBR does what we expect.
306void OpusTest::TestCbrEffect(bool cbr, int block_length_ms) {
307 PrepareSpeechData(channels_, block_length_ms, 2000);
308 const size_t samples = kOpusRateKhz * block_length_ms;
309
310 int32_t max_pkt_size_diff = 0;
311 int32_t prev_pkt_size = 0;
312
313 // Create encoder memory.
314 EXPECT_EQ(0,
315 WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, application_));
316 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
317
318 // Set bitrate.
319 EXPECT_EQ(
320 0, WebRtcOpus_SetBitRate(opus_encoder_, channels_ == 1 ? 32000 : 64000));
321
322 // Setting CBR.
323 EXPECT_EQ(0, cbr ? WebRtcOpus_EnableCbr(opus_encoder_)
324 : WebRtcOpus_DisableCbr(opus_encoder_));
325
326 int16_t audio_type;
327 std::vector<int16_t> audio_out(samples * channels_);
328 for (int i = 0; i < 100; ++i) {
329 EXPECT_EQ(samples, static_cast<size_t>(EncodeDecode(
330 opus_encoder_, speech_data_.GetNextBlock(),
331 opus_decoder_, audio_out.data(), &audio_type)));
332
333 if (prev_pkt_size > 0) {
334 int32_t diff = std::abs((int32_t)encoded_bytes_ - prev_pkt_size);
335 max_pkt_size_diff = std::max(max_pkt_size_diff, diff);
336 }
337 prev_pkt_size = encoded_bytes_;
338 }
339
340 if (cbr) {
341 EXPECT_EQ(max_pkt_size_diff, 0);
342 } else {
343 EXPECT_GT(max_pkt_size_diff, 0);
344 }
345
346 // Free memory.
347 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
348 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
349}
350
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000351// Test failing Create.
henrika1d34fe92015-06-16 10:04:20 +0200352TEST(OpusTest, OpusCreateFail) {
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000353 WebRtcOpusEncInst* opus_encoder;
354 WebRtcOpusDecInst* opus_decoder;
355
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000356 // Test to see that an invalid pointer is caught.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000357 EXPECT_EQ(-1, WebRtcOpus_EncoderCreate(NULL, 1, 0));
358 // Invalid channel number.
359 EXPECT_EQ(-1, WebRtcOpus_EncoderCreate(&opus_encoder, 3, 0));
360 // Invalid applciation mode.
361 EXPECT_EQ(-1, WebRtcOpus_EncoderCreate(&opus_encoder, 1, 2));
362
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000363 EXPECT_EQ(-1, WebRtcOpus_DecoderCreate(NULL, 1));
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000364 // Invalid channel number.
365 EXPECT_EQ(-1, WebRtcOpus_DecoderCreate(&opus_decoder, 3));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000366}
367
368// Test failing Free.
henrika1d34fe92015-06-16 10:04:20 +0200369TEST(OpusTest, OpusFreeFail) {
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000370 // Test to see that an invalid pointer is caught.
371 EXPECT_EQ(-1, WebRtcOpus_EncoderFree(NULL));
372 EXPECT_EQ(-1, WebRtcOpus_DecoderFree(NULL));
373}
374
375// Test normal Create and Free.
henrika1d34fe92015-06-16 10:04:20 +0200376TEST_P(OpusTest, OpusCreateFree) {
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000377 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
378 channels_,
379 application_));
380 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
381 EXPECT_TRUE(opus_encoder_ != NULL);
382 EXPECT_TRUE(opus_decoder_ != NULL);
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000383 // Free encoder and decoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000384 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
385 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000386}
387
henrika1d34fe92015-06-16 10:04:20 +0200388TEST_P(OpusTest, OpusEncodeDecode) {
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000389 PrepareSpeechData(channels_, 20, 20);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000390
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000391 // Create encoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000392 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
393 channels_,
394 application_));
395 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_,
396 channels_));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000397
398 // Set bitrate.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000399 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_,
400 channels_ == 1 ? 32000 : 64000));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000401
402 // Check number of channels for decoder.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000403 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_));
404
405 // Check application mode.
406 opus_int32 app;
407 opus_encoder_ctl(opus_encoder_->encoder,
408 OPUS_GET_APPLICATION(&app));
409 EXPECT_EQ(application_ == 0 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO,
410 app);
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000411
412 // Encode & decode.
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000413 int16_t audio_type;
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000414 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_];
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000415 EXPECT_EQ(kOpus20msFrameSamples,
kwiberg288886b2015-11-06 01:21:35 -0800416 static_cast<size_t>(
417 EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(),
418 opus_decoder_, output_data_decode, &audio_type)));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000419
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000420 // Free memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000421 delete[] output_data_decode;
422 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
423 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000424}
425
henrika1d34fe92015-06-16 10:04:20 +0200426TEST_P(OpusTest, OpusSetBitRate) {
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000427 // Test without creating encoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000428 EXPECT_EQ(-1, WebRtcOpus_SetBitRate(opus_encoder_, 60000));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000429
430 // Create encoder memory, try with different bitrates.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000431 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
432 channels_,
433 application_));
434 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, 30000));
435 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, 60000));
436 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, 300000));
437 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, 600000));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000438
439 // Free memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000440 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000441}
442
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000443TEST_P(OpusTest, OpusSetComplexity) {
minyue@webrtc.org04546882014-03-07 08:55:48 +0000444 // Test without creating encoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000445 EXPECT_EQ(-1, WebRtcOpus_SetComplexity(opus_encoder_, 9));
minyue@webrtc.org04546882014-03-07 08:55:48 +0000446
447 // Create encoder memory, try with different complexities.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000448 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
449 channels_,
450 application_));
minyue@webrtc.org04546882014-03-07 08:55:48 +0000451
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000452 EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_encoder_, 0));
453 EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_encoder_, 10));
454 EXPECT_EQ(-1, WebRtcOpus_SetComplexity(opus_encoder_, 11));
minyue@webrtc.org04546882014-03-07 08:55:48 +0000455
456 // Free memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000457 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
minyue@webrtc.org04546882014-03-07 08:55:48 +0000458}
459
minyuec8299f92016-09-27 02:08:47 -0700460TEST_P(OpusTest, OpusForceChannels) {
461 // Test without creating encoder memory.
462 EXPECT_EQ(-1, WebRtcOpus_SetForceChannels(opus_encoder_, 1));
463
464 ASSERT_EQ(0,
465 WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, application_));
466
467 if (channels_ == 2) {
468 EXPECT_EQ(-1, WebRtcOpus_SetForceChannels(opus_encoder_, 3));
469 EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 2));
470 EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 1));
471 EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 0));
472 } else {
473 EXPECT_EQ(-1, WebRtcOpus_SetForceChannels(opus_encoder_, 2));
474 EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 1));
475 EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 0));
476 }
477
478 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
479}
480
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000481// Encode and decode one frame, initialize the decoder and
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000482// decode once more.
henrika1d34fe92015-06-16 10:04:20 +0200483TEST_P(OpusTest, OpusDecodeInit) {
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000484 PrepareSpeechData(channels_, 20, 20);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000485
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000486 // Create encoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000487 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
488 channels_,
489 application_));
490 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000491
492 // Encode & decode.
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000493 int16_t audio_type;
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000494 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_];
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000495 EXPECT_EQ(kOpus20msFrameSamples,
kwiberg288886b2015-11-06 01:21:35 -0800496 static_cast<size_t>(
497 EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(),
498 opus_decoder_, output_data_decode, &audio_type)));
minyue@webrtc.org52bc4f42014-12-04 11:00:50 +0000499
Karl Wiberg43766482015-08-27 15:22:11 +0200500 WebRtcOpus_DecoderInit(opus_decoder_);
minyue@webrtc.org52bc4f42014-12-04 11:00:50 +0000501
502 EXPECT_EQ(kOpus20msFrameSamples,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700503 static_cast<size_t>(WebRtcOpus_Decode(
504 opus_decoder_, bitstream_, encoded_bytes_, output_data_decode,
505 &audio_type)));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000506
507 // Free memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000508 delete[] output_data_decode;
509 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
510 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000511}
512
henrika1d34fe92015-06-16 10:04:20 +0200513TEST_P(OpusTest, OpusEnableDisableFec) {
minyue@webrtc.org46509c82014-03-07 11:49:11 +0000514 // Test without creating encoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000515 EXPECT_EQ(-1, WebRtcOpus_EnableFec(opus_encoder_));
516 EXPECT_EQ(-1, WebRtcOpus_DisableFec(opus_encoder_));
minyue@webrtc.org46509c82014-03-07 11:49:11 +0000517
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000518 // Create encoder memory.
519 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
520 channels_,
521 application_));
minyue@webrtc.org46509c82014-03-07 11:49:11 +0000522
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000523 EXPECT_EQ(0, WebRtcOpus_EnableFec(opus_encoder_));
524 EXPECT_EQ(0, WebRtcOpus_DisableFec(opus_encoder_));
minyue@webrtc.org46509c82014-03-07 11:49:11 +0000525
526 // Free memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000527 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
minyue@webrtc.org46509c82014-03-07 11:49:11 +0000528}
529
henrika1d34fe92015-06-16 10:04:20 +0200530TEST_P(OpusTest, OpusEnableDisableDtx) {
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000531 // Test without creating encoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000532 EXPECT_EQ(-1, WebRtcOpus_EnableDtx(opus_encoder_));
533 EXPECT_EQ(-1, WebRtcOpus_DisableDtx(opus_encoder_));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000534
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000535 // Create encoder memory.
536 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
537 channels_,
538 application_));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000539
540 opus_int32 dtx;
541
542 // DTX is off by default.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000543 opus_encoder_ctl(opus_encoder_->encoder,
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000544 OPUS_GET_DTX(&dtx));
545 EXPECT_EQ(0, dtx);
546
547 // Test to enable DTX.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000548 EXPECT_EQ(0, WebRtcOpus_EnableDtx(opus_encoder_));
549 opus_encoder_ctl(opus_encoder_->encoder,
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000550 OPUS_GET_DTX(&dtx));
551 EXPECT_EQ(1, dtx);
552
553 // Test to disable DTX.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000554 EXPECT_EQ(0, WebRtcOpus_DisableDtx(opus_encoder_));
555 opus_encoder_ctl(opus_encoder_->encoder,
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000556 OPUS_GET_DTX(&dtx));
557 EXPECT_EQ(0, dtx);
558
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000559
560 // Free memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000561 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000562}
563
henrika1d34fe92015-06-16 10:04:20 +0200564TEST_P(OpusTest, OpusDtxOff) {
minyue3cea2562015-11-10 03:49:26 -0800565 TestDtxEffect(false, 10);
566 TestDtxEffect(false, 20);
567 TestDtxEffect(false, 40);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000568}
569
henrika1d34fe92015-06-16 10:04:20 +0200570TEST_P(OpusTest, OpusDtxOn) {
minyue3cea2562015-11-10 03:49:26 -0800571 TestDtxEffect(true, 10);
572 TestDtxEffect(true, 20);
573 TestDtxEffect(true, 40);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000574}
575
soren28dc2852017-04-06 05:48:36 -0700576TEST_P(OpusTest, OpusCbrOff) {
577 TestCbrEffect(false, 10);
578 TestCbrEffect(false, 20);
579 TestCbrEffect(false, 40);
580}
581
582TEST_P(OpusTest, OpusCbrOn) {
583 TestCbrEffect(true, 10);
584 TestCbrEffect(true, 20);
585 TestCbrEffect(true, 40);
586}
587
henrika1d34fe92015-06-16 10:04:20 +0200588TEST_P(OpusTest, OpusSetPacketLossRate) {
minyue@webrtc.org46509c82014-03-07 11:49:11 +0000589 // Test without creating encoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000590 EXPECT_EQ(-1, WebRtcOpus_SetPacketLossRate(opus_encoder_, 50));
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000591
tina.legrand@webrtc.orgbd21fb52013-08-08 11:01:07 +0000592 // Create encoder memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000593 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
594 channels_,
595 application_));
596
597 EXPECT_EQ(0, WebRtcOpus_SetPacketLossRate(opus_encoder_, 50));
598 EXPECT_EQ(-1, WebRtcOpus_SetPacketLossRate(opus_encoder_, -1));
599 EXPECT_EQ(-1, WebRtcOpus_SetPacketLossRate(opus_encoder_, 101));
600
601 // Free memory.
602 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
603}
604
henrika1d34fe92015-06-16 10:04:20 +0200605TEST_P(OpusTest, OpusSetMaxPlaybackRate) {
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000606 // Test without creating encoder memory.
607 EXPECT_EQ(-1, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, 20000));
608
609 // Create encoder memory.
610 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
611 channels_,
612 application_));
613
614 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_FULLBAND, 48000);
615 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_FULLBAND, 24001);
616 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_SUPERWIDEBAND, 24000);
617 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_SUPERWIDEBAND, 16001);
618 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_WIDEBAND, 16000);
619 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_WIDEBAND, 12001);
620 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_MEDIUMBAND, 12000);
621 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_MEDIUMBAND, 8001);
622 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_NARROWBAND, 8000);
623 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_NARROWBAND, 4000);
624
625 // Free memory.
626 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
627}
628
629// Test PLC.
henrika1d34fe92015-06-16 10:04:20 +0200630TEST_P(OpusTest, OpusDecodePlc) {
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000631 PrepareSpeechData(channels_, 20, 20);
632
633 // Create encoder memory.
634 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
635 channels_,
636 application_));
637 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
tina.legrand@webrtc.orgbd21fb52013-08-08 11:01:07 +0000638
639 // Set bitrate.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000640 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_,
641 channels_== 1 ? 32000 : 64000));
tina.legrand@webrtc.orgbd21fb52013-08-08 11:01:07 +0000642
643 // Check number of channels for decoder.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000644 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_));
tina.legrand@webrtc.orgbd21fb52013-08-08 11:01:07 +0000645
646 // Encode & decode.
tina.legrand@webrtc.orgbd21fb52013-08-08 11:01:07 +0000647 int16_t audio_type;
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000648 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_];
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000649 EXPECT_EQ(kOpus20msFrameSamples,
kwiberg288886b2015-11-06 01:21:35 -0800650 static_cast<size_t>(
651 EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(),
652 opus_decoder_, output_data_decode, &audio_type)));
tina.legrand@webrtc.orgbd21fb52013-08-08 11:01:07 +0000653
minyue@webrtc.org33ccdfa2014-12-04 12:14:12 +0000654 // Call decoder PLC.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000655 int16_t* plc_buffer = new int16_t[kOpus20msFrameSamples * channels_];
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000656 EXPECT_EQ(kOpus20msFrameSamples,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700657 static_cast<size_t>(WebRtcOpus_DecodePlc(
658 opus_decoder_, plc_buffer, 1)));
tina.legrand@webrtc.orgbd21fb52013-08-08 11:01:07 +0000659
660 // Free memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000661 delete[] plc_buffer;
662 delete[] output_data_decode;
663 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
664 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000665}
666
667// Duration estimation.
henrika1d34fe92015-06-16 10:04:20 +0200668TEST_P(OpusTest, OpusDurationEstimation) {
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000669 PrepareSpeechData(channels_, 20, 20);
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000670
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000671 // Create.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000672 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
673 channels_,
674 application_));
675 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000676
minyue@webrtc.org0ca768b2014-12-11 16:09:35 +0000677 // 10 ms. We use only first 10 ms of a 20 ms block.
kwiberg288886b2015-11-06 01:21:35 -0800678 auto speech_block = speech_data_.GetNextBlock();
679 int encoded_bytes_int = WebRtcOpus_Encode(
680 opus_encoder_, speech_block.data(),
Peter Kasting69558702016-01-12 16:26:35 -0800681 rtc::CheckedDivExact(speech_block.size(), 2 * channels_),
kwiberg288886b2015-11-06 01:21:35 -0800682 kMaxBytes, bitstream_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700683 EXPECT_GE(encoded_bytes_int, 0);
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000684 EXPECT_EQ(kOpus10msFrameSamples,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700685 static_cast<size_t>(WebRtcOpus_DurationEst(
686 opus_decoder_, bitstream_,
687 static_cast<size_t>(encoded_bytes_int))));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000688
689 // 20 ms
kwiberg288886b2015-11-06 01:21:35 -0800690 speech_block = speech_data_.GetNextBlock();
691 encoded_bytes_int = WebRtcOpus_Encode(
692 opus_encoder_, speech_block.data(),
Peter Kasting69558702016-01-12 16:26:35 -0800693 rtc::CheckedDivExact(speech_block.size(), channels_),
kwiberg288886b2015-11-06 01:21:35 -0800694 kMaxBytes, bitstream_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700695 EXPECT_GE(encoded_bytes_int, 0);
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000696 EXPECT_EQ(kOpus20msFrameSamples,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700697 static_cast<size_t>(WebRtcOpus_DurationEst(
698 opus_decoder_, bitstream_,
699 static_cast<size_t>(encoded_bytes_int))));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000700
701 // Free memory.
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000702 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
703 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000704}
705
henrika1d34fe92015-06-16 10:04:20 +0200706TEST_P(OpusTest, OpusDecodeRepacketized) {
minyuea613eb62017-03-14 14:33:30 -0700707 constexpr size_t kPackets = 6;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000708
709 PrepareSpeechData(channels_, 20, 20 * kPackets);
710
711 // Create encoder memory.
712 ASSERT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
713 channels_,
714 application_));
715 ASSERT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_,
716 channels_));
717
718 // Set bitrate.
719 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_,
720 channels_ == 1 ? 32000 : 64000));
721
722 // Check number of channels for decoder.
723 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_));
724
725 // Encode & decode.
726 int16_t audio_type;
kwiberg91d97562016-02-14 01:10:03 -0800727 std::unique_ptr<int16_t[]> output_data_decode(
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000728 new int16_t[kPackets * kOpus20msFrameSamples * channels_]);
729 OpusRepacketizer* rp = opus_repacketizer_create();
730
minyuea613eb62017-03-14 14:33:30 -0700731 size_t num_packets = 0;
732 constexpr size_t kMaxCycles = 100;
733 for (size_t idx = 0; idx < kMaxCycles; ++idx) {
kwiberg288886b2015-11-06 01:21:35 -0800734 auto speech_block = speech_data_.GetNextBlock();
735 encoded_bytes_ =
736 WebRtcOpus_Encode(opus_encoder_, speech_block.data(),
Peter Kasting69558702016-01-12 16:26:35 -0800737 rtc::CheckedDivExact(speech_block.size(), channels_),
kwiberg288886b2015-11-06 01:21:35 -0800738 kMaxBytes, bitstream_);
minyuea613eb62017-03-14 14:33:30 -0700739 if (opus_repacketizer_cat(rp, bitstream_, encoded_bytes_) == OPUS_OK) {
740 ++num_packets;
741 if (num_packets == kPackets) {
742 break;
743 }
744 } else {
745 // Opus repacketizer cannot guarantee a success. We try again if it fails.
746 opus_repacketizer_init(rp);
747 num_packets = 0;
748 }
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000749 }
minyuea613eb62017-03-14 14:33:30 -0700750 EXPECT_EQ(kPackets, num_packets);
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000751
752 encoded_bytes_ = opus_repacketizer_out(rp, bitstream_, kMaxBytes);
753
754 EXPECT_EQ(kOpus20msFrameSamples * kPackets,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700755 static_cast<size_t>(WebRtcOpus_DurationEst(
756 opus_decoder_, bitstream_, encoded_bytes_)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000757
758 EXPECT_EQ(kOpus20msFrameSamples * kPackets,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700759 static_cast<size_t>(WebRtcOpus_Decode(
760 opus_decoder_, bitstream_, encoded_bytes_,
761 output_data_decode.get(), &audio_type)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000762
763 // Free memory.
764 opus_repacketizer_destroy(rp);
765 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
766 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
767}
768
minyue@webrtc.org7dba7862015-01-20 16:01:50 +0000769INSTANTIATE_TEST_CASE_P(VariousMode,
770 OpusTest,
771 Combine(Values(1, 2), Values(0, 1)));
772
773
tina.legrand@webrtc.orgdb11fab2013-04-17 10:39:41 +0000774} // namespace webrtc