| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2015 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 | |
| 11 #include "webrtc/base/random.h" | |
| 12 #include "webrtc/base/timeutils.h" | |
| 13 #include "webrtc/system_wrappers/include/sleep.h" | |
| 14 #include "webrtc/test/gtest.h" | |
| 15 #include "webrtc/test/testsupport/fileutils.h" | |
| 16 #include "webrtc/voice_engine/test/auto_test/voe_standard_test.h" | |
| 17 #include "webrtc/voice_engine/test/channel_transport/channel_transport.h" | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 const char kIp[] = "127.0.0.1"; | |
| 22 const int kPort = 1234; | |
| 23 const webrtc::CodecInst kCodecInst = {120, "opus", 48000, 960, 2, 64000}; | |
| 24 | |
| 25 } // namespace | |
| 26 | |
| 27 namespace voetest { | |
| 28 | |
| 29 using webrtc::Random; | |
| 30 using webrtc::test::VoiceChannelTransport; | |
| 31 | |
| 32 // This test allows a check on the output signal in an end-to-end call. | |
| 33 class OutputTest { | |
| 34 public: | |
| 35 OutputTest(int16_t lower_bound, int16_t upper_bound); | |
| 36 ~OutputTest(); | |
| 37 | |
| 38 void Start(); | |
| 39 | |
| 40 void EnableOutputCheck(); | |
| 41 void DisableOutputCheck(); | |
| 42 void SetOutputBound(int16_t lower_bound, int16_t upper_bound); | |
| 43 void Mute(); | |
| 44 void Unmute(); | |
| 45 void SetBitRate(int rate); | |
| 46 | |
| 47 private: | |
| 48 // This class checks all output values and count the number of samples that | |
| 49 // go out of a defined range. | |
| 50 class VoEOutputCheckMediaProcess : public VoEMediaProcess { | |
| 51 public: | |
| 52 VoEOutputCheckMediaProcess(int16_t lower_bound, int16_t upper_bound); | |
| 53 | |
| 54 void set_enabled(bool enabled) { enabled_ = enabled; } | |
| 55 void Process(int channel, | |
| 56 ProcessingTypes type, | |
| 57 int16_t audio10ms[], | |
| 58 size_t length, | |
| 59 int samplingFreq, | |
| 60 bool isStereo) override; | |
| 61 | |
| 62 private: | |
| 63 bool enabled_; | |
| 64 int16_t lower_bound_; | |
| 65 int16_t upper_bound_; | |
| 66 }; | |
| 67 | |
| 68 VoETestManager manager_; | |
| 69 VoEOutputCheckMediaProcess output_checker_; | |
| 70 | |
| 71 int channel_; | |
| 72 }; | |
| 73 | |
| 74 OutputTest::OutputTest(int16_t lower_bound, int16_t upper_bound) | |
| 75 : output_checker_(lower_bound, upper_bound) { | |
| 76 EXPECT_TRUE(manager_.Init()); | |
| 77 manager_.GetInterfaces(); | |
| 78 | |
| 79 VoEBase* base = manager_.BasePtr(); | |
| 80 VoECodec* codec = manager_.CodecPtr(); | |
| 81 VoENetwork* network = manager_.NetworkPtr(); | |
| 82 | |
| 83 EXPECT_EQ(0, base->Init()); | |
| 84 | |
| 85 channel_ = base->CreateChannel(); | |
| 86 | |
| 87 // |network| will take care of the life time of |transport|. | |
| 88 VoiceChannelTransport* transport = | |
| 89 new VoiceChannelTransport(network, channel_); | |
| 90 | |
| 91 EXPECT_EQ(0, transport->SetSendDestination(kIp, kPort)); | |
| 92 EXPECT_EQ(0, transport->SetLocalReceiver(kPort)); | |
| 93 | |
| 94 EXPECT_EQ(0, codec->SetSendCodec(channel_, kCodecInst)); | |
| 95 EXPECT_EQ(0, codec->SetOpusDtx(channel_, true)); | |
| 96 | |
| 97 EXPECT_EQ(0, manager_.VolumeControlPtr()->SetSpeakerVolume(255)); | |
| 98 | |
| 99 manager_.ExternalMediaPtr()->RegisterExternalMediaProcessing( | |
| 100 channel_, ProcessingTypes::kPlaybackPerChannel, output_checker_); | |
| 101 } | |
| 102 | |
| 103 OutputTest::~OutputTest() { | |
| 104 EXPECT_EQ(0, manager_.NetworkPtr()->DeRegisterExternalTransport(channel_)); | |
| 105 EXPECT_EQ(0, manager_.ReleaseInterfaces()); | |
| 106 } | |
| 107 | |
| 108 void OutputTest::Start() { | |
| 109 const std::string file_name = | |
| 110 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); | |
| 111 const webrtc::FileFormats kInputFormat = webrtc::kFileFormatPcm32kHzFile; | |
| 112 | |
| 113 ASSERT_EQ(0, manager_.FilePtr()->StartPlayingFileAsMicrophone( | |
| 114 channel_, file_name.c_str(), true, false, kInputFormat, 1.0)); | |
| 115 | |
| 116 VoEBase* base = manager_.BasePtr(); | |
| 117 ASSERT_EQ(0, base->StartPlayout(channel_)); | |
| 118 ASSERT_EQ(0, base->StartSend(channel_)); | |
| 119 } | |
| 120 | |
| 121 void OutputTest::EnableOutputCheck() { | |
| 122 output_checker_.set_enabled(true); | |
| 123 } | |
| 124 | |
| 125 void OutputTest::DisableOutputCheck() { | |
| 126 output_checker_.set_enabled(false); | |
| 127 } | |
| 128 | |
| 129 void OutputTest::Mute() { | |
| 130 manager_.VolumeControlPtr()->SetInputMute(channel_, true); | |
| 131 } | |
| 132 | |
| 133 void OutputTest::Unmute() { | |
| 134 manager_.VolumeControlPtr()->SetInputMute(channel_, false); | |
| 135 } | |
| 136 | |
| 137 void OutputTest::SetBitRate(int rate) { | |
| 138 manager_.CodecPtr()->SetBitRate(channel_, rate); | |
| 139 } | |
| 140 | |
| 141 OutputTest::VoEOutputCheckMediaProcess::VoEOutputCheckMediaProcess( | |
| 142 int16_t lower_bound, int16_t upper_bound) | |
| 143 : enabled_(false), | |
| 144 lower_bound_(lower_bound), | |
| 145 upper_bound_(upper_bound) {} | |
| 146 | |
| 147 void OutputTest::VoEOutputCheckMediaProcess::Process(int channel, | |
| 148 ProcessingTypes type, | |
| 149 int16_t* audio10ms, | |
| 150 size_t length, | |
| 151 int samplingFreq, | |
| 152 bool isStereo) { | |
| 153 if (!enabled_) | |
| 154 return; | |
| 155 const int num_channels = isStereo ? 2 : 1; | |
| 156 for (size_t i = 0; i < length; ++i) { | |
| 157 for (int c = 0; c < num_channels; ++c) { | |
| 158 ASSERT_GE(audio10ms[i * num_channels + c], lower_bound_); | |
| 159 ASSERT_LE(audio10ms[i * num_channels + c], upper_bound_); | |
| 160 } | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 // This test checks if the Opus does not produce high noise (noise pump) when | |
| 165 // DTX is enabled. The microphone is toggled on and off, and values of the | |
| 166 // output signal during muting should be bounded. | |
| 167 // We do not run this test on bots. Developers that want to see the result | |
| 168 // and/or listen to sound quality can run this test manually. | |
| 169 TEST(OutputTest, DISABLED_OpusDtxHasNoNoisePump) { | |
| 170 const int kRuntimeMs = 20000; | |
| 171 const uint32_t kUnmuteTimeMs = 1000; | |
| 172 const int kCheckAfterMute = 2000; | |
| 173 const uint32_t kCheckTimeMs = 2000; | |
| 174 const int kMinOpusRate = 6000; | |
| 175 const int kMaxOpusRate = 64000; | |
| 176 | |
| 177 #if defined(OPUS_FIXED_POINT) | |
| 178 const int16_t kDtxBoundForSilence = 20; | |
| 179 #else | |
| 180 const int16_t kDtxBoundForSilence = 2; | |
| 181 #endif | |
| 182 | |
| 183 OutputTest test(-kDtxBoundForSilence, kDtxBoundForSilence); | |
| 184 Random random(1234ull); | |
| 185 | |
| 186 int64_t start_time = rtc::TimeMillis(); | |
| 187 test.Start(); | |
| 188 while (rtc::TimeSince(start_time) < kRuntimeMs) { | |
| 189 webrtc::SleepMs(random.Rand(kUnmuteTimeMs - kUnmuteTimeMs / 10, | |
| 190 kUnmuteTimeMs + kUnmuteTimeMs / 10)); | |
| 191 test.Mute(); | |
| 192 webrtc::SleepMs(kCheckAfterMute); | |
| 193 test.EnableOutputCheck(); | |
| 194 webrtc::SleepMs(random.Rand(kCheckTimeMs - kCheckTimeMs / 10, | |
| 195 kCheckTimeMs + kCheckTimeMs / 10)); | |
| 196 test.DisableOutputCheck(); | |
| 197 test.SetBitRate(random.Rand(kMinOpusRate, kMaxOpusRate)); | |
| 198 test.Unmute(); | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 } // namespace voetest | |
| OLD | NEW |