• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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