OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 #include <string> | 10 #include <string> |
(...skipping 24 matching lines...) Loading... |
35 class OpusTest : public TestWithParam<::testing::tuple<int, int>> { | 35 class OpusTest : public TestWithParam<::testing::tuple<int, int>> { |
36 protected: | 36 protected: |
37 OpusTest(); | 37 OpusTest(); |
38 | 38 |
39 void TestDtxEffect(bool dtx, int block_length_ms); | 39 void TestDtxEffect(bool dtx, int block_length_ms); |
40 | 40 |
41 // Prepare |speech_data_| for encoding, read from a hard-coded file. | 41 // Prepare |speech_data_| for encoding, read from a hard-coded file. |
42 // After preparation, |speech_data_.GetNextBlock()| returns a pointer to a | 42 // After preparation, |speech_data_.GetNextBlock()| returns a pointer to a |
43 // block of |block_length_ms| milliseconds. The data is looped every | 43 // block of |block_length_ms| milliseconds. The data is looped every |
44 // |loop_length_ms| milliseconds. | 44 // |loop_length_ms| milliseconds. |
45 void PrepareSpeechData(int channel, int block_length_ms, int loop_length_ms); | 45 void PrepareSpeechData(size_t channel, |
| 46 int block_length_ms, |
| 47 int loop_length_ms); |
46 | 48 |
47 int EncodeDecode(WebRtcOpusEncInst* encoder, | 49 int EncodeDecode(WebRtcOpusEncInst* encoder, |
48 rtc::ArrayView<const int16_t> input_audio, | 50 rtc::ArrayView<const int16_t> input_audio, |
49 WebRtcOpusDecInst* decoder, | 51 WebRtcOpusDecInst* decoder, |
50 int16_t* output_audio, | 52 int16_t* output_audio, |
51 int16_t* audio_type); | 53 int16_t* audio_type); |
52 | 54 |
53 void SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, | 55 void SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, |
54 opus_int32 expect, int32_t set); | 56 opus_int32 expect, int32_t set); |
55 | 57 |
56 void CheckAudioBounded(const int16_t* audio, size_t samples, int channels, | 58 void CheckAudioBounded(const int16_t* audio, size_t samples, size_t channels, |
57 uint16_t bound) const; | 59 uint16_t bound) const; |
58 | 60 |
59 WebRtcOpusEncInst* opus_encoder_; | 61 WebRtcOpusEncInst* opus_encoder_; |
60 WebRtcOpusDecInst* opus_decoder_; | 62 WebRtcOpusDecInst* opus_decoder_; |
61 | 63 |
62 AudioLoop speech_data_; | 64 AudioLoop speech_data_; |
63 uint8_t bitstream_[kMaxBytes]; | 65 uint8_t bitstream_[kMaxBytes]; |
64 size_t encoded_bytes_; | 66 size_t encoded_bytes_; |
65 int channels_; | 67 size_t channels_; |
66 int application_; | 68 int application_; |
67 }; | 69 }; |
68 | 70 |
69 OpusTest::OpusTest() | 71 OpusTest::OpusTest() |
70 : opus_encoder_(NULL), | 72 : opus_encoder_(NULL), |
71 opus_decoder_(NULL), | 73 opus_decoder_(NULL), |
72 encoded_bytes_(0), | 74 encoded_bytes_(0), |
73 channels_(::testing::get<0>(GetParam())), | 75 channels_(static_cast<size_t>(::testing::get<0>(GetParam()))), |
74 application_(::testing::get<1>(GetParam())) { | 76 application_(::testing::get<1>(GetParam())) { |
75 } | 77 } |
76 | 78 |
77 void OpusTest::PrepareSpeechData(int channel, int block_length_ms, | 79 void OpusTest::PrepareSpeechData(size_t channel, int block_length_ms, |
78 int loop_length_ms) { | 80 int loop_length_ms) { |
79 const std::string file_name = | 81 const std::string file_name = |
80 webrtc::test::ResourcePath((channel == 1) ? | 82 webrtc::test::ResourcePath((channel == 1) ? |
81 "audio_coding/testfile32kHz" : | 83 "audio_coding/testfile32kHz" : |
82 "audio_coding/teststereo32kHz", "pcm"); | 84 "audio_coding/teststereo32kHz", "pcm"); |
83 if (loop_length_ms < block_length_ms) { | 85 if (loop_length_ms < block_length_ms) { |
84 loop_length_ms = block_length_ms; | 86 loop_length_ms = block_length_ms; |
85 } | 87 } |
86 EXPECT_TRUE(speech_data_.Init(file_name, | 88 EXPECT_TRUE(speech_data_.Init(file_name, |
87 loop_length_ms * kOpusRateKhz * channel, | 89 loop_length_ms * kOpusRateKhz * channel, |
88 block_length_ms * kOpusRateKhz * channel)); | 90 block_length_ms * kOpusRateKhz * channel)); |
89 } | 91 } |
90 | 92 |
91 void OpusTest::SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, | 93 void OpusTest::SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, |
92 opus_int32 expect, | 94 opus_int32 expect, |
93 int32_t set) { | 95 int32_t set) { |
94 opus_int32 bandwidth; | 96 opus_int32 bandwidth; |
95 EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, set)); | 97 EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, set)); |
96 opus_encoder_ctl(opus_encoder_->encoder, | 98 opus_encoder_ctl(opus_encoder_->encoder, |
97 OPUS_GET_MAX_BANDWIDTH(&bandwidth)); | 99 OPUS_GET_MAX_BANDWIDTH(&bandwidth)); |
98 EXPECT_EQ(expect, bandwidth); | 100 EXPECT_EQ(expect, bandwidth); |
99 } | 101 } |
100 | 102 |
101 void OpusTest::CheckAudioBounded(const int16_t* audio, size_t samples, | 103 void OpusTest::CheckAudioBounded(const int16_t* audio, size_t samples, |
102 int channels, uint16_t bound) const { | 104 size_t channels, uint16_t bound) const { |
103 for (size_t i = 0; i < samples; ++i) { | 105 for (size_t i = 0; i < samples; ++i) { |
104 for (int c = 0; c < channels; ++c) { | 106 for (size_t c = 0; c < channels; ++c) { |
105 ASSERT_GE(audio[i * channels + c], -bound); | 107 ASSERT_GE(audio[i * channels + c], -bound); |
106 ASSERT_LE(audio[i * channels + c], bound); | 108 ASSERT_LE(audio[i * channels + c], bound); |
107 } | 109 } |
108 } | 110 } |
109 } | 111 } |
110 | 112 |
111 int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder, | 113 int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder, |
112 rtc::ArrayView<const int16_t> input_audio, | 114 rtc::ArrayView<const int16_t> input_audio, |
113 WebRtcOpusDecInst* decoder, | 115 WebRtcOpusDecInst* decoder, |
114 int16_t* output_audio, | 116 int16_t* output_audio, |
115 int16_t* audio_type) { | 117 int16_t* audio_type) { |
116 int encoded_bytes_int = WebRtcOpus_Encode( | 118 int encoded_bytes_int = WebRtcOpus_Encode( |
117 encoder, input_audio.data(), | 119 encoder, input_audio.data(), |
118 rtc::CheckedDivExact(input_audio.size(), static_cast<size_t>(channels_)), | 120 rtc::CheckedDivExact(input_audio.size(), channels_), |
119 kMaxBytes, bitstream_); | 121 kMaxBytes, bitstream_); |
120 EXPECT_GE(encoded_bytes_int, 0); | 122 EXPECT_GE(encoded_bytes_int, 0); |
121 encoded_bytes_ = static_cast<size_t>(encoded_bytes_int); | 123 encoded_bytes_ = static_cast<size_t>(encoded_bytes_int); |
122 int est_len = WebRtcOpus_DurationEst(decoder, bitstream_, encoded_bytes_); | 124 int est_len = WebRtcOpus_DurationEst(decoder, bitstream_, encoded_bytes_); |
123 int act_len = WebRtcOpus_Decode(decoder, bitstream_, | 125 int act_len = WebRtcOpus_Decode(decoder, bitstream_, |
124 encoded_bytes_, output_audio, | 126 encoded_bytes_, output_audio, |
125 audio_type); | 127 audio_type); |
126 EXPECT_EQ(est_len, act_len); | 128 EXPECT_EQ(est_len, act_len); |
127 return act_len; | 129 return act_len; |
128 } | 130 } |
(...skipping 452 matching lines...) Loading... |
581 // Create. | 583 // Create. |
582 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, | 584 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, |
583 channels_, | 585 channels_, |
584 application_)); | 586 application_)); |
585 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); | 587 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); |
586 | 588 |
587 // 10 ms. We use only first 10 ms of a 20 ms block. | 589 // 10 ms. We use only first 10 ms of a 20 ms block. |
588 auto speech_block = speech_data_.GetNextBlock(); | 590 auto speech_block = speech_data_.GetNextBlock(); |
589 int encoded_bytes_int = WebRtcOpus_Encode( | 591 int encoded_bytes_int = WebRtcOpus_Encode( |
590 opus_encoder_, speech_block.data(), | 592 opus_encoder_, speech_block.data(), |
591 rtc::CheckedDivExact(speech_block.size(), | 593 rtc::CheckedDivExact(speech_block.size(), 2 * channels_), |
592 2 * static_cast<size_t>(channels_)), | |
593 kMaxBytes, bitstream_); | 594 kMaxBytes, bitstream_); |
594 EXPECT_GE(encoded_bytes_int, 0); | 595 EXPECT_GE(encoded_bytes_int, 0); |
595 EXPECT_EQ(kOpus10msFrameSamples, | 596 EXPECT_EQ(kOpus10msFrameSamples, |
596 static_cast<size_t>(WebRtcOpus_DurationEst( | 597 static_cast<size_t>(WebRtcOpus_DurationEst( |
597 opus_decoder_, bitstream_, | 598 opus_decoder_, bitstream_, |
598 static_cast<size_t>(encoded_bytes_int)))); | 599 static_cast<size_t>(encoded_bytes_int)))); |
599 | 600 |
600 // 20 ms | 601 // 20 ms |
601 speech_block = speech_data_.GetNextBlock(); | 602 speech_block = speech_data_.GetNextBlock(); |
602 encoded_bytes_int = WebRtcOpus_Encode( | 603 encoded_bytes_int = WebRtcOpus_Encode( |
603 opus_encoder_, speech_block.data(), | 604 opus_encoder_, speech_block.data(), |
604 rtc::CheckedDivExact(speech_block.size(), static_cast<size_t>(channels_)), | 605 rtc::CheckedDivExact(speech_block.size(), channels_), |
605 kMaxBytes, bitstream_); | 606 kMaxBytes, bitstream_); |
606 EXPECT_GE(encoded_bytes_int, 0); | 607 EXPECT_GE(encoded_bytes_int, 0); |
607 EXPECT_EQ(kOpus20msFrameSamples, | 608 EXPECT_EQ(kOpus20msFrameSamples, |
608 static_cast<size_t>(WebRtcOpus_DurationEst( | 609 static_cast<size_t>(WebRtcOpus_DurationEst( |
609 opus_decoder_, bitstream_, | 610 opus_decoder_, bitstream_, |
610 static_cast<size_t>(encoded_bytes_int)))); | 611 static_cast<size_t>(encoded_bytes_int)))); |
611 | 612 |
612 // Free memory. | 613 // Free memory. |
613 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); | 614 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); |
614 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); | 615 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); |
(...skipping 21 matching lines...) Loading... |
636 // Encode & decode. | 637 // Encode & decode. |
637 int16_t audio_type; | 638 int16_t audio_type; |
638 rtc::scoped_ptr<int16_t[]> output_data_decode( | 639 rtc::scoped_ptr<int16_t[]> output_data_decode( |
639 new int16_t[kPackets * kOpus20msFrameSamples * channels_]); | 640 new int16_t[kPackets * kOpus20msFrameSamples * channels_]); |
640 OpusRepacketizer* rp = opus_repacketizer_create(); | 641 OpusRepacketizer* rp = opus_repacketizer_create(); |
641 | 642 |
642 for (int idx = 0; idx < kPackets; idx++) { | 643 for (int idx = 0; idx < kPackets; idx++) { |
643 auto speech_block = speech_data_.GetNextBlock(); | 644 auto speech_block = speech_data_.GetNextBlock(); |
644 encoded_bytes_ = | 645 encoded_bytes_ = |
645 WebRtcOpus_Encode(opus_encoder_, speech_block.data(), | 646 WebRtcOpus_Encode(opus_encoder_, speech_block.data(), |
646 rtc::CheckedDivExact(speech_block.size(), | 647 rtc::CheckedDivExact(speech_block.size(), channels_), |
647 static_cast<size_t>(channels_)), | |
648 kMaxBytes, bitstream_); | 648 kMaxBytes, bitstream_); |
649 EXPECT_EQ(OPUS_OK, opus_repacketizer_cat(rp, bitstream_, encoded_bytes_)); | 649 EXPECT_EQ(OPUS_OK, opus_repacketizer_cat(rp, bitstream_, encoded_bytes_)); |
650 } | 650 } |
651 | 651 |
652 encoded_bytes_ = opus_repacketizer_out(rp, bitstream_, kMaxBytes); | 652 encoded_bytes_ = opus_repacketizer_out(rp, bitstream_, kMaxBytes); |
653 | 653 |
654 EXPECT_EQ(kOpus20msFrameSamples * kPackets, | 654 EXPECT_EQ(kOpus20msFrameSamples * kPackets, |
655 static_cast<size_t>(WebRtcOpus_DurationEst( | 655 static_cast<size_t>(WebRtcOpus_DurationEst( |
656 opus_decoder_, bitstream_, encoded_bytes_))); | 656 opus_decoder_, bitstream_, encoded_bytes_))); |
657 | 657 |
658 EXPECT_EQ(kOpus20msFrameSamples * kPackets, | 658 EXPECT_EQ(kOpus20msFrameSamples * kPackets, |
659 static_cast<size_t>(WebRtcOpus_Decode( | 659 static_cast<size_t>(WebRtcOpus_Decode( |
660 opus_decoder_, bitstream_, encoded_bytes_, | 660 opus_decoder_, bitstream_, encoded_bytes_, |
661 output_data_decode.get(), &audio_type))); | 661 output_data_decode.get(), &audio_type))); |
662 | 662 |
663 // Free memory. | 663 // Free memory. |
664 opus_repacketizer_destroy(rp); | 664 opus_repacketizer_destroy(rp); |
665 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); | 665 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); |
666 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); | 666 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); |
667 } | 667 } |
668 | 668 |
669 INSTANTIATE_TEST_CASE_P(VariousMode, | 669 INSTANTIATE_TEST_CASE_P(VariousMode, |
670 OpusTest, | 670 OpusTest, |
671 Combine(Values(1, 2), Values(0, 1))); | 671 Combine(Values(1, 2), Values(0, 1))); |
672 | 672 |
673 | 673 |
674 } // namespace webrtc | 674 } // namespace webrtc |
OLD | NEW |