blob: 8c28db703c01fbb5e6c5d2e64ddea914945f2290 [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"
14#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
15#include "webrtc/modules/audio_device/include/mock_audio_device.h"
16#include "webrtc/modules/audio_processing/include/audio_processing.h"
17#include "webrtc/test/gmock.h"
18#include "webrtc/test/gtest.h"
19#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)
126 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false,
127 kAgcFixedDigital);
128 EXPECT_FALSE(gc->is_enabled());
129 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
130
131 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true,
132 kAgcFixedDigital);
133 EXPECT_TRUE(gc->is_enabled());
134 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
135#else
136 EXPECT_CALL(*helper.adm(), SetAGC(false)).WillOnce(testing::Return(0));
137 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false,
138 kAgcAdaptiveAnalog);
139 EXPECT_FALSE(gc->is_enabled());
140 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
141
142 EXPECT_CALL(*helper.adm(), SetAGC(true)).WillOnce(testing::Return(0));
143 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true,
144 kAgcAdaptiveAnalog);
145 EXPECT_TRUE(gc->is_enabled());
146 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
147#endif
148}
149
150TEST(ApmHelpersTest, EcStatus_DefaultMode) {
151 TestHelper helper;
152 EchoCancellation* ec = helper.apm()->echo_cancellation();
153 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
154 EXPECT_FALSE(ec->is_enabled());
155 EXPECT_FALSE(ecm->is_enabled());
156}
157
158TEST(ApmHelpersTest, EcStatus_EnableDisable) {
159 TestHelper helper;
160 EchoCancellation* ec = helper.apm()->echo_cancellation();
161 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
162
163 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
164 EXPECT_FALSE(ec->is_enabled());
165 EXPECT_TRUE(ecm->is_enabled());
166
167 apm_helpers::SetEcStatus(helper.apm(), false, kEcAecm);
168 EXPECT_FALSE(ec->is_enabled());
169 EXPECT_FALSE(ecm->is_enabled());
170
171 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
172 EXPECT_TRUE(ec->is_enabled());
173 EXPECT_FALSE(ecm->is_enabled());
174 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
175
176 apm_helpers::SetEcStatus(helper.apm(), false, kEcConference);
177 EXPECT_FALSE(ec->is_enabled());
178 EXPECT_FALSE(ecm->is_enabled());
179 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
180
181 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
182 EXPECT_FALSE(ec->is_enabled());
183 EXPECT_TRUE(ecm->is_enabled());
184}
185
186TEST(ApmHelpersTest, EcMetrics_DefaultMode) {
187 TestHelper helper;
188 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
189 EXPECT_TRUE(helper.GetEcMetricsStatus());
190}
191
192TEST(ApmHelpersTest, EcMetrics_CanEnableDisable) {
193 TestHelper helper;
194 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
195
196 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
197 EXPECT_TRUE(helper.GetEcMetricsStatus());
198 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
199 EXPECT_FALSE(helper.GetEcMetricsStatus());
200}
201
202TEST(ApmHelpersTest, EcMetrics_NoStatsUnlessEcMetricsAndEcEnabled) {
203 TestHelper helper;
204 EXPECT_FALSE(helper.CanGetEcMetrics());
205
206 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
207 EXPECT_FALSE(helper.CanGetEcMetrics());
208
209 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
210 EXPECT_TRUE(helper.CanGetEcMetrics());
211
212 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
213 EXPECT_FALSE(helper.CanGetEcMetrics());
214}
215
216TEST(ApmHelpersTest, AecmMode_DefaultMode) {
217 TestHelper helper;
218 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
219 EXPECT_EQ(EchoControlMobile::kSpeakerphone, ecm->routing_mode());
220 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
221}
222
223TEST(ApmHelpersTest, AecmMode_EnableDisableCng) {
224 TestHelper helper;
225 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
226 apm_helpers::SetAecmMode(helper.apm(), false);
227 EXPECT_FALSE(ecm->is_comfort_noise_enabled());
228 apm_helpers::SetAecmMode(helper.apm(), true);
229 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
230}
231
232TEST(ApmHelpersTest, NsStatus_DefaultMode) {
233 TestHelper helper;
234 NoiseSuppression* ns = helper.apm()->noise_suppression();
235 EXPECT_EQ(NoiseSuppression::kModerate, ns->level());
236 EXPECT_FALSE(ns->is_enabled());
237}
238
239TEST(ApmHelpersTest, NsStatus_EnableDisable) {
240 TestHelper helper;
241 NoiseSuppression* ns = helper.apm()->noise_suppression();
242 apm_helpers::SetNsStatus(helper.apm(), true);
243 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
244 EXPECT_TRUE(ns->is_enabled());
245 apm_helpers::SetNsStatus(helper.apm(), false);
246 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
247 EXPECT_FALSE(ns->is_enabled());
248}
249
250TEST(ApmHelpersTest, TypingDetectionStatus_DefaultMode) {
251 TestHelper helper;
252 VoiceDetection* vd = helper.apm()->voice_detection();
253 EXPECT_FALSE(vd->is_enabled());
254}
255
256TEST(ApmHelpersTest, TypingDetectionStatus_EnableDisable) {
257 TestHelper helper;
258 VoiceDetection* vd = helper.apm()->voice_detection();
259 apm_helpers::SetTypingDetectionStatus(helper.apm(), true);
260 EXPECT_TRUE(vd->is_enabled());
261 apm_helpers::SetTypingDetectionStatus(helper.apm(), false);
262 EXPECT_FALSE(vd->is_enabled());
263}
264
265// TODO(solenberg): Move this test to a better place - added here for the sake
266// of duplicating all relevant tests from audio_processing_test.cc.
267TEST(ApmHelpersTest, HighPassFilter_DefaultMode) {
268 TestHelper helper;
269 EXPECT_TRUE(helper.apm()->high_pass_filter()->is_enabled());
270}
271
272// TODO(solenberg): Move this test to a better place - added here for the sake
273// of duplicating all relevant tests from audio_processing_test.cc.
274TEST(ApmHelpersTest, StereoSwapping_DefaultMode) {
275 TestHelper helper;
276 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
277}
278
279// TODO(solenberg): Move this test to a better place - added here for the sake
280// of duplicating all relevant tests from audio_processing_test.cc.
281TEST(ApmHelpersTest, StereoSwapping_EnableDisable) {
282 TestHelper helper;
283 helper.transmit_mixer()->EnableStereoChannelSwapping(true);
284 EXPECT_TRUE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
285 helper.transmit_mixer()->EnableStereoChannelSwapping(false);
286 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
287}
288} // namespace webrtc