1835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org/* 2835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org * 4835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org * Use of this source code is governed by a BSD-style license 5835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org * that can be found in the LICENSE file in the root of the source 6835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org * tree. An additional intellectual property rights grant can be found 7835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org * in the file PATENTS. All contributing project authors may 8835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org */ 10835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 11835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org#include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h" 12e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h" 13835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org#include "webrtc/test/testsupport/fileutils.h" 14835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 15835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgusing google::RegisterFlagValidator; 16835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgusing google::ParseCommandLineFlags; 17835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgusing std::string; 18835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgusing testing::InitGoogleTest; 19835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 20835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgnamespace webrtc { 21835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgnamespace test { 22835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 23835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic const int kOpusBlockDurationMs = 20; 24254879d7e969771c28d0882582e02b1a0b0eeb14minyue@webrtc.orgstatic const int kOpusSamplingKhz = 48; 25835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 26b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org// Define switch for input file name. 27835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic bool ValidateInFilename(const char* flagname, const string& value) { 28835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org FILE* fid = fopen(value.c_str(), "rb"); 29835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org if (fid != NULL) { 30835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org fclose(fid); 31835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return true; 32835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org } 33835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org printf("Invalid input filename."); 34835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return false; 35835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 36b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 37835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgDEFINE_string(in_filename, 38835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org ResourcePath("audio_coding/speech_mono_32_48kHz", "pcm"), 39835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org "Filename for input audio (should be 48 kHz sampled raw data)."); 40b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 41835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic const bool in_filename_dummy = 42835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org RegisterFlagValidator(&FLAGS_in_filename, &ValidateInFilename); 43835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 44b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org// Define switch for output file name. 45835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic bool ValidateOutFilename(const char* flagname, const string& value) { 46835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org FILE* fid = fopen(value.c_str(), "wb"); 47835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org if (fid != NULL) { 48835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org fclose(fid); 49835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return true; 50835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org } 51835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org printf("Invalid output filename."); 52835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return false; 53835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 54b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 55835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgDEFINE_string(out_filename, OutputPath() + "neteq4_opus_fec_quality_test.pcm", 56835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org "Name of output audio file."); 57b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 58835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic const bool out_filename_dummy = 59835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org RegisterFlagValidator(&FLAGS_out_filename, &ValidateOutFilename); 60835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 61b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org// Define switch for channels. 62835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic bool ValidateChannels(const char* flagname, int32_t value) { 63835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org if (value == 1 || value == 2) 64835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return true; 65835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org printf("Invalid number of channels, should be either 1 or 2."); 66835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return false; 67835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 68b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 69835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgDEFINE_int32(channels, 1, "Number of channels in input audio."); 70b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 71835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic const bool channels_dummy = 72835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org RegisterFlagValidator(&FLAGS_channels, &ValidateChannels); 73835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 74b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org// Define switch for bit rate. 75835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic bool ValidateBitRate(const char* flagname, int32_t value) { 76835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org if (value >= 6 && value <= 510) 77835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return true; 78835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org printf("Invalid bit rate, should be between 6 and 510 kbps."); 79835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return false; 80835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 81b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 82835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgDEFINE_int32(bit_rate_kbps, 32, "Target bit rate (kbps)."); 83b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 84835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic const bool bit_rate_dummy = 85835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org RegisterFlagValidator(&FLAGS_bit_rate_kbps, &ValidateBitRate); 86835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 87b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org// Define switch for reported packet loss rate. 88835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic bool ValidatePacketLossRate(const char* flagname, int32_t value) { 89835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org if (value >= 0 && value <= 100) 90835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return true; 91835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org printf("Invalid packet loss percentile, should be between 0 and 100."); 92835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return false; 93835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 94b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 95835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgDEFINE_int32(reported_loss_rate, 10, "Reported percentile of packet loss."); 96b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 97835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic const bool reported_loss_rate_dummy = 98835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org RegisterFlagValidator(&FLAGS_reported_loss_rate, &ValidatePacketLossRate); 99835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 100b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org// Define switch for runtime. 101835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic bool ValidateRuntime(const char* flagname, int32_t value) { 102835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org if (value > 0) 103835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return true; 104835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org printf("Invalid runtime, should be greater than 0."); 105835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return false; 106835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 107b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org 108835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgDEFINE_int32(runtime_ms, 10000, "Simulated runtime (milliseconds)."); 109835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgstatic const bool runtime_dummy = 110835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org RegisterFlagValidator(&FLAGS_runtime_ms, &ValidateRuntime); 111835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 112835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgDEFINE_bool(fec, true, "Whether to enable FEC for encoding."); 113835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 114835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgclass NetEqOpusFecQualityTest : public NetEqQualityTest { 115835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org protected: 116835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org NetEqOpusFecQualityTest(); 117835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org virtual void SetUp() OVERRIDE; 118835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org virtual void TearDown() OVERRIDE; 119835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org virtual int EncodeBlock(int16_t* in_data, int block_size_samples, 120835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org uint8_t* payload, int max_bytes); 121835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org private: 122835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org WebRtcOpusEncInst* opus_encoder_; 123835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org int channels_; 124835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org int bit_rate_kbps_; 125835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org bool fec_; 126835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org int target_loss_rate_; 127835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org}; 128835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 129835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgNetEqOpusFecQualityTest::NetEqOpusFecQualityTest() 130254879d7e969771c28d0882582e02b1a0b0eeb14minyue@webrtc.org : NetEqQualityTest(kOpusBlockDurationMs, kOpusSamplingKhz, 131254879d7e969771c28d0882582e02b1a0b0eeb14minyue@webrtc.org kOpusSamplingKhz, 132835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org (FLAGS_channels == 1) ? kDecoderOpus : kDecoderOpus_2ch, 133b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org FLAGS_channels, 134b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org FLAGS_in_filename, 135835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org FLAGS_out_filename), 136835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org opus_encoder_(NULL), 137835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org channels_(FLAGS_channels), 138835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org bit_rate_kbps_(FLAGS_bit_rate_kbps), 139835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org fec_(FLAGS_fec), 140b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org target_loss_rate_(FLAGS_reported_loss_rate) { 141835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 142835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 143835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgvoid NetEqOpusFecQualityTest::SetUp() { 144835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org // Create encoder memory. 145835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org WebRtcOpus_EncoderCreate(&opus_encoder_, channels_); 146835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org ASSERT_TRUE(opus_encoder_ != NULL); 147835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org // Set bitrate. 148835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, bit_rate_kbps_ * 1000)); 149835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org if (fec_) { 150835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org EXPECT_EQ(0, WebRtcOpus_EnableFec(opus_encoder_)); 151835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org } 152b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org EXPECT_EQ(0, WebRtcOpus_SetPacketLossRate(opus_encoder_, 153b5272dfc7e7599580263bcde04b0484a6379f2b9minyue@webrtc.org target_loss_rate_)); 154835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org NetEqQualityTest::SetUp(); 155835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 156835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 157835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgvoid NetEqOpusFecQualityTest::TearDown() { 158835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org // Free memory. 159835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); 160835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org NetEqQualityTest::TearDown(); 161835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 162835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 163835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgint NetEqOpusFecQualityTest::EncodeBlock(int16_t* in_data, 164835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org int block_size_samples, 165835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org uint8_t* payload, int max_bytes) { 166835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org int value = WebRtcOpus_Encode(opus_encoder_, in_data, 167835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org block_size_samples, max_bytes, 168835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org payload); 169835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org EXPECT_GT(value, 0); 170835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org return value; 171835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 172835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 173835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.orgTEST_F(NetEqOpusFecQualityTest, Test) { 174835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org Simulate(FLAGS_runtime_ms); 175835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} 176835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org 177835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} // namespace test 178835b016d936aeb6c48b42c211ef257d6d3057c4fminyue@webrtc.org} // namespace webrtc 179