| 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...) Expand all 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand all 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 |