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