• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
20 namespace {
21 
22 const char kIp[] = "127.0.0.1";
23 const int kPort = 1234;
24 const webrtc::CodecInst kCodecInst = {120, "opus", 48000, 960, 2, 64000};
25 
26 }  // namespace
27 
28 namespace voetest {
29 
30 using webrtc::Random;
31 using webrtc::test::VoiceChannelTransport;
32 
33 // This test allows a check on the output signal in an end-to-end call.
34 class 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 
set_enabled(bool enabled)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 
OutputTest(int16_t lower_bound,int16_t upper_bound)75 OutputTest::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 
~OutputTest()104 OutputTest::~OutputTest() {
105   EXPECT_EQ(0, manager_.NetworkPtr()->DeRegisterExternalTransport(channel_));
106   EXPECT_EQ(0, manager_.ReleaseInterfaces());
107 }
108 
Start()109 void 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 
EnableOutputCheck()122 void OutputTest::EnableOutputCheck() {
123   output_checker_.set_enabled(true);
124 }
125 
DisableOutputCheck()126 void OutputTest::DisableOutputCheck() {
127   output_checker_.set_enabled(false);
128 }
129 
Mute()130 void OutputTest::Mute() {
131   manager_.VolumeControlPtr()->SetInputMute(channel_, true);
132 }
133 
Unmute()134 void OutputTest::Unmute() {
135   manager_.VolumeControlPtr()->SetInputMute(channel_, false);
136 }
137 
SetBitRate(int rate)138 void OutputTest::SetBitRate(int rate) {
139   manager_.CodecPtr()->SetBitRate(channel_, rate);
140 }
141 
VoEOutputCheckMediaProcess(int16_t lower_bound,int16_t upper_bound)142 OutputTest::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 
Process(int channel,ProcessingTypes type,int16_t * audio10ms,size_t length,int samplingFreq,bool isStereo)148 void 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.
TEST(OutputTest,DISABLED_OpusDtxHasNoNoisePump)170 TEST(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