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