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