1 /*
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 */
10 #include <string>
11
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "webrtc/base/checks.h"
14 #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h"
15 #include "webrtc/modules/audio_coding/codecs/opus/opus_inst.h"
16 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h"
17 #include "webrtc/test/testsupport/fileutils.h"
18
19 namespace webrtc {
20
21 using test::AudioLoop;
22 using ::testing::TestWithParam;
23 using ::testing::Values;
24 using ::testing::Combine;
25
26 // Maximum number of bytes in output bitstream.
27 const size_t kMaxBytes = 1000;
28 // Sample rate of Opus.
29 const size_t kOpusRateKhz = 48;
30 // Number of samples-per-channel in a 20 ms frame, sampled at 48 kHz.
31 const size_t kOpus20msFrameSamples = kOpusRateKhz * 20;
32 // Number of samples-per-channel in a 10 ms frame, sampled at 48 kHz.
33 const size_t kOpus10msFrameSamples = kOpusRateKhz * 10;
34
35 class OpusTest : public TestWithParam<::testing::tuple<int, int>> {
36 protected:
37 OpusTest();
38
39 void TestDtxEffect(bool dtx, int block_length_ms);
40
41 // Prepare |speech_data_| for encoding, read from a hard-coded file.
42 // After preparation, |speech_data_.GetNextBlock()| returns a pointer to a
43 // block of |block_length_ms| milliseconds. The data is looped every
44 // |loop_length_ms| milliseconds.
45 void PrepareSpeechData(size_t channel,
46 int block_length_ms,
47 int loop_length_ms);
48
49 int EncodeDecode(WebRtcOpusEncInst* encoder,
50 rtc::ArrayView<const int16_t> input_audio,
51 WebRtcOpusDecInst* decoder,
52 int16_t* output_audio,
53 int16_t* audio_type);
54
55 void SetMaxPlaybackRate(WebRtcOpusEncInst* encoder,
56 opus_int32 expect, int32_t set);
57
58 void CheckAudioBounded(const int16_t* audio, size_t samples, size_t channels,
59 uint16_t bound) const;
60
61 WebRtcOpusEncInst* opus_encoder_;
62 WebRtcOpusDecInst* opus_decoder_;
63
64 AudioLoop speech_data_;
65 uint8_t bitstream_[kMaxBytes];
66 size_t encoded_bytes_;
67 size_t channels_;
68 int application_;
69 };
70
OpusTest()71 OpusTest::OpusTest()
72 : opus_encoder_(NULL),
73 opus_decoder_(NULL),
74 encoded_bytes_(0),
75 channels_(static_cast<size_t>(::testing::get<0>(GetParam()))),
76 application_(::testing::get<1>(GetParam())) {
77 }
78
PrepareSpeechData(size_t channel,int block_length_ms,int loop_length_ms)79 void OpusTest::PrepareSpeechData(size_t channel, int block_length_ms,
80 int loop_length_ms) {
81 const std::string file_name =
82 webrtc::test::ResourcePath((channel == 1) ?
83 "audio_coding/testfile32kHz" :
84 "audio_coding/teststereo32kHz", "pcm");
85 if (loop_length_ms < block_length_ms) {
86 loop_length_ms = block_length_ms;
87 }
88 EXPECT_TRUE(speech_data_.Init(file_name,
89 loop_length_ms * kOpusRateKhz * channel,
90 block_length_ms * kOpusRateKhz * channel));
91 }
92
SetMaxPlaybackRate(WebRtcOpusEncInst * encoder,opus_int32 expect,int32_t set)93 void OpusTest::SetMaxPlaybackRate(WebRtcOpusEncInst* encoder,
94 opus_int32 expect,
95 int32_t set) {
96 opus_int32 bandwidth;
97 EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, set));
98 opus_encoder_ctl(opus_encoder_->encoder,
99 OPUS_GET_MAX_BANDWIDTH(&bandwidth));
100 EXPECT_EQ(expect, bandwidth);
101 }
102
CheckAudioBounded(const int16_t * audio,size_t samples,size_t channels,uint16_t bound) const103 void OpusTest::CheckAudioBounded(const int16_t* audio, size_t samples,
104 size_t channels, uint16_t bound) const {
105 for (size_t i = 0; i < samples; ++i) {
106 for (size_t c = 0; c < channels; ++c) {
107 ASSERT_GE(audio[i * channels + c], -bound);
108 ASSERT_LE(audio[i * channels + c], bound);
109 }
110 }
111 }
112
EncodeDecode(WebRtcOpusEncInst * encoder,rtc::ArrayView<const int16_t> input_audio,WebRtcOpusDecInst * decoder,int16_t * output_audio,int16_t * audio_type)113 int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder,
114 rtc::ArrayView<const int16_t> input_audio,
115 WebRtcOpusDecInst* decoder,
116 int16_t* output_audio,
117 int16_t* audio_type) {
118 int encoded_bytes_int = WebRtcOpus_Encode(
119 encoder, input_audio.data(),
120 rtc::CheckedDivExact(input_audio.size(), channels_),
121 kMaxBytes, bitstream_);
122 EXPECT_GE(encoded_bytes_int, 0);
123 encoded_bytes_ = static_cast<size_t>(encoded_bytes_int);
124 int est_len = WebRtcOpus_DurationEst(decoder, bitstream_, encoded_bytes_);
125 int act_len = WebRtcOpus_Decode(decoder, bitstream_,
126 encoded_bytes_, output_audio,
127 audio_type);
128 EXPECT_EQ(est_len, act_len);
129 return act_len;
130 }
131
132 // Test if encoder/decoder can enter DTX mode properly and do not enter DTX when
133 // they should not. This test is signal dependent.
TestDtxEffect(bool dtx,int block_length_ms)134 void OpusTest::TestDtxEffect(bool dtx, int block_length_ms) {
135 PrepareSpeechData(channels_, block_length_ms, 2000);
136 const size_t samples = kOpusRateKhz * block_length_ms;
137
138 // Create encoder memory.
139 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
140 channels_,
141 application_));
142 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
143
144 // Set bitrate.
145 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_,
146 channels_ == 1 ? 32000 : 64000));
147
148 // Set input audio as silence.
149 std::vector<int16_t> silence(samples * channels_, 0);
150
151 // Setting DTX.
152 EXPECT_EQ(0, dtx ? WebRtcOpus_EnableDtx(opus_encoder_) :
153 WebRtcOpus_DisableDtx(opus_encoder_));
154
155 int16_t audio_type;
156 int16_t* output_data_decode = new int16_t[samples * channels_];
157
158 for (int i = 0; i < 100; ++i) {
159 EXPECT_EQ(samples,
160 static_cast<size_t>(EncodeDecode(
161 opus_encoder_, speech_data_.GetNextBlock(), opus_decoder_,
162 output_data_decode, &audio_type)));
163 // If not DTX, it should never enter DTX mode. If DTX, we do not care since
164 // whether it enters DTX depends on the signal type.
165 if (!dtx) {
166 EXPECT_GT(encoded_bytes_, 1U);
167 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
168 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
169 EXPECT_EQ(0, audio_type); // Speech.
170 }
171 }
172
173 // We input some silent segments. In DTX mode, the encoder will stop sending.
174 // However, DTX may happen after a while.
175 for (int i = 0; i < 30; ++i) {
176 EXPECT_EQ(samples,
177 static_cast<size_t>(EncodeDecode(
178 opus_encoder_, silence, opus_decoder_, output_data_decode,
179 &audio_type)));
180 if (!dtx) {
181 EXPECT_GT(encoded_bytes_, 1U);
182 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
183 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
184 EXPECT_EQ(0, audio_type); // Speech.
185 } else if (encoded_bytes_ == 1) {
186 EXPECT_EQ(1, opus_encoder_->in_dtx_mode);
187 EXPECT_EQ(1, opus_decoder_->in_dtx_mode);
188 EXPECT_EQ(2, audio_type); // Comfort noise.
189 break;
190 }
191 }
192
193 // When Opus is in DTX, it wakes up in a regular basis. It sends two packets,
194 // one with an arbitrary size and the other of 1-byte, then stops sending for
195 // a certain number of frames.
196
197 // |max_dtx_frames| is the maximum number of frames Opus can stay in DTX.
198 const int max_dtx_frames = 400 / block_length_ms + 1;
199
200 // We run |kRunTimeMs| milliseconds of pure silence.
201 const int kRunTimeMs = 2000;
202
203 // We check that, after a |kCheckTimeMs| milliseconds (given that the CNG in
204 // Opus needs time to adapt), the absolute values of DTX decoded signal are
205 // bounded by |kOutputValueBound|.
206 const int kCheckTimeMs = 1500;
207
208 #if defined(OPUS_FIXED_POINT)
209 const uint16_t kOutputValueBound = 20;
210 #else
211 const uint16_t kOutputValueBound = 2;
212 #endif
213
214 int time = 0;
215 while (time < kRunTimeMs) {
216 // DTX mode is maintained for maximum |max_dtx_frames| frames.
217 int i = 0;
218 for (; i < max_dtx_frames; ++i) {
219 time += block_length_ms;
220 EXPECT_EQ(samples,
221 static_cast<size_t>(EncodeDecode(
222 opus_encoder_, silence, opus_decoder_, output_data_decode,
223 &audio_type)));
224 if (dtx) {
225 if (encoded_bytes_ > 1)
226 break;
227 EXPECT_EQ(0U, encoded_bytes_) // Send 0 byte.
228 << "Opus should have entered DTX mode.";
229 EXPECT_EQ(1, opus_encoder_->in_dtx_mode);
230 EXPECT_EQ(1, opus_decoder_->in_dtx_mode);
231 EXPECT_EQ(2, audio_type); // Comfort noise.
232 if (time >= kCheckTimeMs) {
233 CheckAudioBounded(output_data_decode, samples, channels_,
234 kOutputValueBound);
235 }
236 } else {
237 EXPECT_GT(encoded_bytes_, 1U);
238 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
239 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
240 EXPECT_EQ(0, audio_type); // Speech.
241 }
242 }
243
244 if (dtx) {
245 // With DTX, Opus must stop transmission for some time.
246 EXPECT_GT(i, 1);
247 }
248
249 // We expect a normal payload.
250 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
251 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
252 EXPECT_EQ(0, audio_type); // Speech.
253
254 // Enters DTX again immediately.
255 time += block_length_ms;
256 EXPECT_EQ(samples,
257 static_cast<size_t>(EncodeDecode(
258 opus_encoder_, silence, opus_decoder_, output_data_decode,
259 &audio_type)));
260 if (dtx) {
261 EXPECT_EQ(1U, encoded_bytes_); // Send 1 byte.
262 EXPECT_EQ(1, opus_encoder_->in_dtx_mode);
263 EXPECT_EQ(1, opus_decoder_->in_dtx_mode);
264 EXPECT_EQ(2, audio_type); // Comfort noise.
265 if (time >= kCheckTimeMs) {
266 CheckAudioBounded(output_data_decode, samples, channels_,
267 kOutputValueBound);
268 }
269 } else {
270 EXPECT_GT(encoded_bytes_, 1U);
271 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
272 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
273 EXPECT_EQ(0, audio_type); // Speech.
274 }
275 }
276
277 silence[0] = 10000;
278 if (dtx) {
279 // Verify that encoder/decoder can jump out from DTX mode.
280 EXPECT_EQ(samples,
281 static_cast<size_t>(EncodeDecode(
282 opus_encoder_, silence, opus_decoder_, output_data_decode,
283 &audio_type)));
284 EXPECT_GT(encoded_bytes_, 1U);
285 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
286 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
287 EXPECT_EQ(0, audio_type); // Speech.
288 }
289
290 // Free memory.
291 delete[] output_data_decode;
292 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
293 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
294 }
295
296 // Test failing Create.
TEST(OpusTest,OpusCreateFail)297 TEST(OpusTest, OpusCreateFail) {
298 WebRtcOpusEncInst* opus_encoder;
299 WebRtcOpusDecInst* opus_decoder;
300
301 // Test to see that an invalid pointer is caught.
302 EXPECT_EQ(-1, WebRtcOpus_EncoderCreate(NULL, 1, 0));
303 // Invalid channel number.
304 EXPECT_EQ(-1, WebRtcOpus_EncoderCreate(&opus_encoder, 3, 0));
305 // Invalid applciation mode.
306 EXPECT_EQ(-1, WebRtcOpus_EncoderCreate(&opus_encoder, 1, 2));
307
308 EXPECT_EQ(-1, WebRtcOpus_DecoderCreate(NULL, 1));
309 // Invalid channel number.
310 EXPECT_EQ(-1, WebRtcOpus_DecoderCreate(&opus_decoder, 3));
311 }
312
313 // Test failing Free.
TEST(OpusTest,OpusFreeFail)314 TEST(OpusTest, OpusFreeFail) {
315 // Test to see that an invalid pointer is caught.
316 EXPECT_EQ(-1, WebRtcOpus_EncoderFree(NULL));
317 EXPECT_EQ(-1, WebRtcOpus_DecoderFree(NULL));
318 }
319
320 // Test normal Create and Free.
TEST_P(OpusTest,OpusCreateFree)321 TEST_P(OpusTest, OpusCreateFree) {
322 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
323 channels_,
324 application_));
325 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
326 EXPECT_TRUE(opus_encoder_ != NULL);
327 EXPECT_TRUE(opus_decoder_ != NULL);
328 // Free encoder and decoder memory.
329 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
330 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
331 }
332
TEST_P(OpusTest,OpusEncodeDecode)333 TEST_P(OpusTest, OpusEncodeDecode) {
334 PrepareSpeechData(channels_, 20, 20);
335
336 // Create encoder memory.
337 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
338 channels_,
339 application_));
340 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_,
341 channels_));
342
343 // Set bitrate.
344 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_,
345 channels_ == 1 ? 32000 : 64000));
346
347 // Check number of channels for decoder.
348 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_));
349
350 // Check application mode.
351 opus_int32 app;
352 opus_encoder_ctl(opus_encoder_->encoder,
353 OPUS_GET_APPLICATION(&app));
354 EXPECT_EQ(application_ == 0 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO,
355 app);
356
357 // Encode & decode.
358 int16_t audio_type;
359 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_];
360 EXPECT_EQ(kOpus20msFrameSamples,
361 static_cast<size_t>(
362 EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(),
363 opus_decoder_, output_data_decode, &audio_type)));
364
365 // Free memory.
366 delete[] output_data_decode;
367 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
368 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
369 }
370
TEST_P(OpusTest,OpusSetBitRate)371 TEST_P(OpusTest, OpusSetBitRate) {
372 // Test without creating encoder memory.
373 EXPECT_EQ(-1, WebRtcOpus_SetBitRate(opus_encoder_, 60000));
374
375 // Create encoder memory, try with different bitrates.
376 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
377 channels_,
378 application_));
379 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, 30000));
380 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, 60000));
381 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, 300000));
382 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, 600000));
383
384 // Free memory.
385 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
386 }
387
TEST_P(OpusTest,OpusSetComplexity)388 TEST_P(OpusTest, OpusSetComplexity) {
389 // Test without creating encoder memory.
390 EXPECT_EQ(-1, WebRtcOpus_SetComplexity(opus_encoder_, 9));
391
392 // Create encoder memory, try with different complexities.
393 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
394 channels_,
395 application_));
396
397 EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_encoder_, 0));
398 EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_encoder_, 10));
399 EXPECT_EQ(-1, WebRtcOpus_SetComplexity(opus_encoder_, 11));
400
401 // Free memory.
402 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
403 }
404
405 // Encode and decode one frame, initialize the decoder and
406 // decode once more.
TEST_P(OpusTest,OpusDecodeInit)407 TEST_P(OpusTest, OpusDecodeInit) {
408 PrepareSpeechData(channels_, 20, 20);
409
410 // Create encoder memory.
411 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
412 channels_,
413 application_));
414 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
415
416 // Encode & decode.
417 int16_t audio_type;
418 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_];
419 EXPECT_EQ(kOpus20msFrameSamples,
420 static_cast<size_t>(
421 EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(),
422 opus_decoder_, output_data_decode, &audio_type)));
423
424 WebRtcOpus_DecoderInit(opus_decoder_);
425
426 EXPECT_EQ(kOpus20msFrameSamples,
427 static_cast<size_t>(WebRtcOpus_Decode(
428 opus_decoder_, bitstream_, encoded_bytes_, output_data_decode,
429 &audio_type)));
430
431 // Free memory.
432 delete[] output_data_decode;
433 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
434 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
435 }
436
TEST_P(OpusTest,OpusEnableDisableFec)437 TEST_P(OpusTest, OpusEnableDisableFec) {
438 // Test without creating encoder memory.
439 EXPECT_EQ(-1, WebRtcOpus_EnableFec(opus_encoder_));
440 EXPECT_EQ(-1, WebRtcOpus_DisableFec(opus_encoder_));
441
442 // Create encoder memory.
443 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
444 channels_,
445 application_));
446
447 EXPECT_EQ(0, WebRtcOpus_EnableFec(opus_encoder_));
448 EXPECT_EQ(0, WebRtcOpus_DisableFec(opus_encoder_));
449
450 // Free memory.
451 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
452 }
453
TEST_P(OpusTest,OpusEnableDisableDtx)454 TEST_P(OpusTest, OpusEnableDisableDtx) {
455 // Test without creating encoder memory.
456 EXPECT_EQ(-1, WebRtcOpus_EnableDtx(opus_encoder_));
457 EXPECT_EQ(-1, WebRtcOpus_DisableDtx(opus_encoder_));
458
459 // Create encoder memory.
460 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
461 channels_,
462 application_));
463
464 opus_int32 dtx;
465
466 // DTX is off by default.
467 opus_encoder_ctl(opus_encoder_->encoder,
468 OPUS_GET_DTX(&dtx));
469 EXPECT_EQ(0, dtx);
470
471 // Test to enable DTX.
472 EXPECT_EQ(0, WebRtcOpus_EnableDtx(opus_encoder_));
473 opus_encoder_ctl(opus_encoder_->encoder,
474 OPUS_GET_DTX(&dtx));
475 EXPECT_EQ(1, dtx);
476
477 // Test to disable DTX.
478 EXPECT_EQ(0, WebRtcOpus_DisableDtx(opus_encoder_));
479 opus_encoder_ctl(opus_encoder_->encoder,
480 OPUS_GET_DTX(&dtx));
481 EXPECT_EQ(0, dtx);
482
483
484 // Free memory.
485 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
486 }
487
TEST_P(OpusTest,OpusDtxOff)488 TEST_P(OpusTest, OpusDtxOff) {
489 TestDtxEffect(false, 10);
490 TestDtxEffect(false, 20);
491 TestDtxEffect(false, 40);
492 }
493
TEST_P(OpusTest,OpusDtxOn)494 TEST_P(OpusTest, OpusDtxOn) {
495 TestDtxEffect(true, 10);
496 TestDtxEffect(true, 20);
497 TestDtxEffect(true, 40);
498 }
499
TEST_P(OpusTest,OpusSetPacketLossRate)500 TEST_P(OpusTest, OpusSetPacketLossRate) {
501 // Test without creating encoder memory.
502 EXPECT_EQ(-1, WebRtcOpus_SetPacketLossRate(opus_encoder_, 50));
503
504 // Create encoder memory.
505 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
506 channels_,
507 application_));
508
509 EXPECT_EQ(0, WebRtcOpus_SetPacketLossRate(opus_encoder_, 50));
510 EXPECT_EQ(-1, WebRtcOpus_SetPacketLossRate(opus_encoder_, -1));
511 EXPECT_EQ(-1, WebRtcOpus_SetPacketLossRate(opus_encoder_, 101));
512
513 // Free memory.
514 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
515 }
516
TEST_P(OpusTest,OpusSetMaxPlaybackRate)517 TEST_P(OpusTest, OpusSetMaxPlaybackRate) {
518 // Test without creating encoder memory.
519 EXPECT_EQ(-1, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, 20000));
520
521 // Create encoder memory.
522 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
523 channels_,
524 application_));
525
526 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_FULLBAND, 48000);
527 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_FULLBAND, 24001);
528 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_SUPERWIDEBAND, 24000);
529 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_SUPERWIDEBAND, 16001);
530 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_WIDEBAND, 16000);
531 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_WIDEBAND, 12001);
532 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_MEDIUMBAND, 12000);
533 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_MEDIUMBAND, 8001);
534 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_NARROWBAND, 8000);
535 SetMaxPlaybackRate(opus_encoder_, OPUS_BANDWIDTH_NARROWBAND, 4000);
536
537 // Free memory.
538 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
539 }
540
541 // Test PLC.
TEST_P(OpusTest,OpusDecodePlc)542 TEST_P(OpusTest, OpusDecodePlc) {
543 PrepareSpeechData(channels_, 20, 20);
544
545 // Create encoder memory.
546 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
547 channels_,
548 application_));
549 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
550
551 // Set bitrate.
552 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_,
553 channels_== 1 ? 32000 : 64000));
554
555 // Check number of channels for decoder.
556 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_));
557
558 // Encode & decode.
559 int16_t audio_type;
560 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_];
561 EXPECT_EQ(kOpus20msFrameSamples,
562 static_cast<size_t>(
563 EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(),
564 opus_decoder_, output_data_decode, &audio_type)));
565
566 // Call decoder PLC.
567 int16_t* plc_buffer = new int16_t[kOpus20msFrameSamples * channels_];
568 EXPECT_EQ(kOpus20msFrameSamples,
569 static_cast<size_t>(WebRtcOpus_DecodePlc(
570 opus_decoder_, plc_buffer, 1)));
571
572 // Free memory.
573 delete[] plc_buffer;
574 delete[] output_data_decode;
575 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
576 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
577 }
578
579 // Duration estimation.
TEST_P(OpusTest,OpusDurationEstimation)580 TEST_P(OpusTest, OpusDurationEstimation) {
581 PrepareSpeechData(channels_, 20, 20);
582
583 // Create.
584 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
585 channels_,
586 application_));
587 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
588
589 // 10 ms. We use only first 10 ms of a 20 ms block.
590 auto speech_block = speech_data_.GetNextBlock();
591 int encoded_bytes_int = WebRtcOpus_Encode(
592 opus_encoder_, speech_block.data(),
593 rtc::CheckedDivExact(speech_block.size(), 2 * channels_),
594 kMaxBytes, bitstream_);
595 EXPECT_GE(encoded_bytes_int, 0);
596 EXPECT_EQ(kOpus10msFrameSamples,
597 static_cast<size_t>(WebRtcOpus_DurationEst(
598 opus_decoder_, bitstream_,
599 static_cast<size_t>(encoded_bytes_int))));
600
601 // 20 ms
602 speech_block = speech_data_.GetNextBlock();
603 encoded_bytes_int = WebRtcOpus_Encode(
604 opus_encoder_, speech_block.data(),
605 rtc::CheckedDivExact(speech_block.size(), channels_),
606 kMaxBytes, bitstream_);
607 EXPECT_GE(encoded_bytes_int, 0);
608 EXPECT_EQ(kOpus20msFrameSamples,
609 static_cast<size_t>(WebRtcOpus_DurationEst(
610 opus_decoder_, bitstream_,
611 static_cast<size_t>(encoded_bytes_int))));
612
613 // Free memory.
614 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
615 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
616 }
617
TEST_P(OpusTest,OpusDecodeRepacketized)618 TEST_P(OpusTest, OpusDecodeRepacketized) {
619 const int kPackets = 6;
620
621 PrepareSpeechData(channels_, 20, 20 * kPackets);
622
623 // Create encoder memory.
624 ASSERT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_,
625 channels_,
626 application_));
627 ASSERT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_,
628 channels_));
629
630 // Set bitrate.
631 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_,
632 channels_ == 1 ? 32000 : 64000));
633
634 // Check number of channels for decoder.
635 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_));
636
637 // Encode & decode.
638 int16_t audio_type;
639 rtc::scoped_ptr<int16_t[]> output_data_decode(
640 new int16_t[kPackets * kOpus20msFrameSamples * channels_]);
641 OpusRepacketizer* rp = opus_repacketizer_create();
642
643 for (int idx = 0; idx < kPackets; idx++) {
644 auto speech_block = speech_data_.GetNextBlock();
645 encoded_bytes_ =
646 WebRtcOpus_Encode(opus_encoder_, speech_block.data(),
647 rtc::CheckedDivExact(speech_block.size(), channels_),
648 kMaxBytes, bitstream_);
649 EXPECT_EQ(OPUS_OK, opus_repacketizer_cat(rp, bitstream_, encoded_bytes_));
650 }
651
652 encoded_bytes_ = opus_repacketizer_out(rp, bitstream_, kMaxBytes);
653
654 EXPECT_EQ(kOpus20msFrameSamples * kPackets,
655 static_cast<size_t>(WebRtcOpus_DurationEst(
656 opus_decoder_, bitstream_, encoded_bytes_)));
657
658 EXPECT_EQ(kOpus20msFrameSamples * kPackets,
659 static_cast<size_t>(WebRtcOpus_Decode(
660 opus_decoder_, bitstream_, encoded_bytes_,
661 output_data_decode.get(), &audio_type)));
662
663 // Free memory.
664 opus_repacketizer_destroy(rp);
665 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
666 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
667 }
668
669 INSTANTIATE_TEST_CASE_P(VariousMode,
670 OpusTest,
671 Combine(Values(1, 2), Values(0, 1)));
672
673
674 } // namespace webrtc
675