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