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
19namespace webrtc {
20
21using test::AudioLoop;
22using ::testing::TestWithParam;
23using ::testing::Values;
24using ::testing::Combine;
25
26// Maximum number of bytes in output bitstream.
27const size_t kMaxBytes = 1000;
28// Sample rate of Opus.
29const size_t kOpusRateKhz = 48;
30// Number of samples-per-channel in a 20 ms frame, sampled at 48 kHz.
31const size_t kOpus20msFrameSamples = kOpusRateKhz * 20;
32// Number of samples-per-channel in a 10 ms frame, sampled at 48 kHz.
33const size_t kOpus10msFrameSamples = kOpusRateKhz * 10;
34
35class 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
71OpusTest::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
79void 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
93void 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
103void 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
113int 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.
134void 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.
297TEST(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.
314TEST(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.
321TEST_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
333TEST_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
371TEST_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
388TEST_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.
407TEST_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
437TEST_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
454TEST_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
488TEST_P(OpusTest, OpusDtxOff) {
489  TestDtxEffect(false, 10);
490  TestDtxEffect(false, 20);
491  TestDtxEffect(false, 40);
492}
493
494TEST_P(OpusTest, OpusDtxOn) {
495  TestDtxEffect(true, 10);
496  TestDtxEffect(true, 20);
497  TestDtxEffect(true, 40);
498}
499
500TEST_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
517TEST_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.
542TEST_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.
580TEST_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
618TEST_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
669INSTANTIATE_TEST_CASE_P(VariousMode,
670                        OpusTest,
671                        Combine(Values(1, 2), Values(0, 1)));
672
673
674}  // namespace webrtc
675