blob: f7c418d3324286a63dff6418594b32b4d006eb58 [file] [log] [blame]
solenberg76377c52017-02-21 00:54:31 -08001/*
2 * Copyright (c) 2017 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/media/engine/apm_helpers.h"
12
13#include "webrtc/media/engine/webrtcvoe.h"
solenberg76377c52017-02-21 00:54:31 -080014#include "webrtc/modules/audio_device/include/mock_audio_device.h"
15#include "webrtc/modules/audio_processing/include/audio_processing.h"
16#include "webrtc/test/gmock.h"
17#include "webrtc/test/gtest.h"
kwiberg37e99fd2017-04-10 05:15:48 -070018#include "webrtc/test/mock_audio_decoder_factory.h"
solenberg76377c52017-02-21 00:54:31 -080019#include "webrtc/voice_engine/transmit_mixer.h"
20
21namespace webrtc {
22namespace {
23
24constexpr AgcConfig kDefaultAgcConfig = { 3, 9, true };
25
26struct TestHelper {
27 TestHelper() {
tommif0d7b2b2017-03-03 01:34:15 -080028 // Reply with a 10ms timer every time TimeUntilNextProcess is called to
29 // avoid entering a tight loop on the process thread.
30 EXPECT_CALL(mock_audio_device_, TimeUntilNextProcess())
31 .WillRepeatedly(testing::Return(10));
32
solenberg76377c52017-02-21 00:54:31 -080033 // This replicates the conditions from voe_auto_test.
34 Config config;
35 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
36 EXPECT_EQ(0, voe_wrapper_.base()->Init(
37 &mock_audio_device_,
38 AudioProcessing::Create(config),
39 MockAudioDecoderFactory::CreateEmptyFactory()));
40 }
41
42 AudioProcessing* apm() {
43 return voe_wrapper_.base()->audio_processing();
44 }
45
46 const AudioProcessing* apm() const {
47 return voe_wrapper_.base()->audio_processing();
48 }
49
50 test::MockAudioDeviceModule* adm() {
51 return &mock_audio_device_;
52 }
53
54 voe::TransmitMixer* transmit_mixer() {
55 return voe_wrapper_.base()->transmit_mixer();
56 }
57
58 bool GetEcMetricsStatus() const {
59 EchoCancellation* ec = apm()->echo_cancellation();
60 bool metrics_enabled = ec->are_metrics_enabled();
61 EXPECT_EQ(metrics_enabled, ec->is_delay_logging_enabled());
62 return metrics_enabled;
63 }
64
65 bool CanGetEcMetrics() const {
66 EchoCancellation* ec = apm()->echo_cancellation();
67 EchoCancellation::Metrics metrics;
68 int metrics_result = ec->GetMetrics(&metrics);
69 int median = 0;
70 int std = 0;
71 float fraction = 0;
72 int delay_metrics_result = ec->GetDelayMetrics(&median, &std, &fraction);
73 return metrics_result == AudioProcessing::kNoError &&
74 delay_metrics_result == AudioProcessing::kNoError;
75 }
76
77 private:
78 testing::NiceMock<test::MockAudioDeviceModule> mock_audio_device_;
79 cricket::VoEWrapper voe_wrapper_;
80};
81} // namespace
82
83TEST(ApmHelpersTest, AgcConfig_DefaultConfiguration) {
84 TestHelper helper;
85 AgcConfig agc_config =
86 apm_helpers::GetAgcConfig(helper.apm());
87
88 EXPECT_EQ(kDefaultAgcConfig.targetLeveldBOv, agc_config.targetLeveldBOv);
89 EXPECT_EQ(kDefaultAgcConfig.digitalCompressionGaindB,
90 agc_config.digitalCompressionGaindB);
91 EXPECT_EQ(kDefaultAgcConfig.limiterEnable, agc_config.limiterEnable);
92}
93
94TEST(ApmHelpersTest, AgcConfig_GetAndSet) {
95 const AgcConfig agc_config = { 11, 17, false };
96
97 TestHelper helper;
98 apm_helpers::SetAgcConfig(helper.apm(), agc_config);
99 AgcConfig actual_config =
100 apm_helpers::GetAgcConfig(helper.apm());
101
102 EXPECT_EQ(agc_config.digitalCompressionGaindB,
103 actual_config.digitalCompressionGaindB);
104 EXPECT_EQ(agc_config.limiterEnable,
105 actual_config.limiterEnable);
106 EXPECT_EQ(agc_config.targetLeveldBOv,
107 actual_config.targetLeveldBOv);
108}
109
110TEST(ApmHelpersTest, AgcStatus_DefaultMode) {
111 TestHelper helper;
112 GainControl* gc = helper.apm()->gain_control();
113#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
114 EXPECT_FALSE(gc->is_enabled());
115 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
116#else
117 EXPECT_TRUE(gc->is_enabled());
118 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
119#endif
120}
121
122TEST(ApmHelpersTest, AgcStatus_EnableDisable) {
123 TestHelper helper;
124 GainControl* gc = helper.apm()->gain_control();
125#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
solenberg22818a52017-03-16 01:20:23 -0700126 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false);
solenberg76377c52017-02-21 00:54:31 -0800127 EXPECT_FALSE(gc->is_enabled());
128 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
129
solenberg22818a52017-03-16 01:20:23 -0700130 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
solenberg76377c52017-02-21 00:54:31 -0800131 EXPECT_TRUE(gc->is_enabled());
132 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
133#else
134 EXPECT_CALL(*helper.adm(), SetAGC(false)).WillOnce(testing::Return(0));
solenberg22818a52017-03-16 01:20:23 -0700135 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false);
solenberg76377c52017-02-21 00:54:31 -0800136 EXPECT_FALSE(gc->is_enabled());
137 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
138
139 EXPECT_CALL(*helper.adm(), SetAGC(true)).WillOnce(testing::Return(0));
solenberg22818a52017-03-16 01:20:23 -0700140 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
solenberg76377c52017-02-21 00:54:31 -0800141 EXPECT_TRUE(gc->is_enabled());
142 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
143#endif
144}
145
146TEST(ApmHelpersTest, EcStatus_DefaultMode) {
147 TestHelper helper;
148 EchoCancellation* ec = helper.apm()->echo_cancellation();
149 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
150 EXPECT_FALSE(ec->is_enabled());
151 EXPECT_FALSE(ecm->is_enabled());
152}
153
154TEST(ApmHelpersTest, EcStatus_EnableDisable) {
155 TestHelper helper;
156 EchoCancellation* ec = helper.apm()->echo_cancellation();
157 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
158
159 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
160 EXPECT_FALSE(ec->is_enabled());
161 EXPECT_TRUE(ecm->is_enabled());
162
163 apm_helpers::SetEcStatus(helper.apm(), false, kEcAecm);
164 EXPECT_FALSE(ec->is_enabled());
165 EXPECT_FALSE(ecm->is_enabled());
166
167 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
168 EXPECT_TRUE(ec->is_enabled());
169 EXPECT_FALSE(ecm->is_enabled());
170 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
171
172 apm_helpers::SetEcStatus(helper.apm(), false, kEcConference);
173 EXPECT_FALSE(ec->is_enabled());
174 EXPECT_FALSE(ecm->is_enabled());
175 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
176
177 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
178 EXPECT_FALSE(ec->is_enabled());
179 EXPECT_TRUE(ecm->is_enabled());
180}
181
182TEST(ApmHelpersTest, EcMetrics_DefaultMode) {
183 TestHelper helper;
184 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
185 EXPECT_TRUE(helper.GetEcMetricsStatus());
186}
187
188TEST(ApmHelpersTest, EcMetrics_CanEnableDisable) {
189 TestHelper helper;
190 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
191
192 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
193 EXPECT_TRUE(helper.GetEcMetricsStatus());
194 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
195 EXPECT_FALSE(helper.GetEcMetricsStatus());
196}
197
198TEST(ApmHelpersTest, EcMetrics_NoStatsUnlessEcMetricsAndEcEnabled) {
199 TestHelper helper;
200 EXPECT_FALSE(helper.CanGetEcMetrics());
201
202 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
203 EXPECT_FALSE(helper.CanGetEcMetrics());
204
205 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
206 EXPECT_TRUE(helper.CanGetEcMetrics());
207
208 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
209 EXPECT_FALSE(helper.CanGetEcMetrics());
210}
211
212TEST(ApmHelpersTest, AecmMode_DefaultMode) {
213 TestHelper helper;
214 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
215 EXPECT_EQ(EchoControlMobile::kSpeakerphone, ecm->routing_mode());
216 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
217}
218
219TEST(ApmHelpersTest, AecmMode_EnableDisableCng) {
220 TestHelper helper;
221 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
222 apm_helpers::SetAecmMode(helper.apm(), false);
223 EXPECT_FALSE(ecm->is_comfort_noise_enabled());
224 apm_helpers::SetAecmMode(helper.apm(), true);
225 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
226}
227
228TEST(ApmHelpersTest, NsStatus_DefaultMode) {
229 TestHelper helper;
230 NoiseSuppression* ns = helper.apm()->noise_suppression();
231 EXPECT_EQ(NoiseSuppression::kModerate, ns->level());
232 EXPECT_FALSE(ns->is_enabled());
233}
234
235TEST(ApmHelpersTest, NsStatus_EnableDisable) {
236 TestHelper helper;
237 NoiseSuppression* ns = helper.apm()->noise_suppression();
238 apm_helpers::SetNsStatus(helper.apm(), true);
239 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
240 EXPECT_TRUE(ns->is_enabled());
241 apm_helpers::SetNsStatus(helper.apm(), false);
242 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
243 EXPECT_FALSE(ns->is_enabled());
244}
245
246TEST(ApmHelpersTest, TypingDetectionStatus_DefaultMode) {
247 TestHelper helper;
248 VoiceDetection* vd = helper.apm()->voice_detection();
249 EXPECT_FALSE(vd->is_enabled());
250}
251
252TEST(ApmHelpersTest, TypingDetectionStatus_EnableDisable) {
253 TestHelper helper;
254 VoiceDetection* vd = helper.apm()->voice_detection();
255 apm_helpers::SetTypingDetectionStatus(helper.apm(), true);
256 EXPECT_TRUE(vd->is_enabled());
257 apm_helpers::SetTypingDetectionStatus(helper.apm(), false);
258 EXPECT_FALSE(vd->is_enabled());
259}
260
261// TODO(solenberg): Move this test to a better place - added here for the sake
262// of duplicating all relevant tests from audio_processing_test.cc.
263TEST(ApmHelpersTest, HighPassFilter_DefaultMode) {
264 TestHelper helper;
265 EXPECT_TRUE(helper.apm()->high_pass_filter()->is_enabled());
266}
267
268// TODO(solenberg): Move this test to a better place - added here for the sake
269// of duplicating all relevant tests from audio_processing_test.cc.
270TEST(ApmHelpersTest, StereoSwapping_DefaultMode) {
271 TestHelper helper;
272 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
273}
274
275// TODO(solenberg): Move this test to a better place - added here for the sake
276// of duplicating all relevant tests from audio_processing_test.cc.
277TEST(ApmHelpersTest, StereoSwapping_EnableDisable) {
278 TestHelper helper;
279 helper.transmit_mixer()->EnableStereoChannelSwapping(true);
280 EXPECT_TRUE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
281 helper.transmit_mixer()->EnableStereoChannelSwapping(false);
282 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
283}
284} // namespace webrtc