blob: 6845d9e454bb28df14f4497025b22b86daea7c3c [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();
oprypin45197522017-06-22 01:47:20 -0700113#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
114 EXPECT_FALSE(gc->is_enabled());
115 EXPECT_EQ(GainControl::kAdaptiveDigital, gc->mode());
116#elif defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
solenberg76377c52017-02-21 00:54:31 -0800117 EXPECT_FALSE(gc->is_enabled());
118 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
119#else
120 EXPECT_TRUE(gc->is_enabled());
121 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
122#endif
123}
124
125TEST(ApmHelpersTest, AgcStatus_EnableDisable) {
126 TestHelper helper;
127 GainControl* gc = helper.apm()->gain_control();
128#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
solenberg22818a52017-03-16 01:20:23 -0700129 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false);
solenberg76377c52017-02-21 00:54:31 -0800130 EXPECT_FALSE(gc->is_enabled());
131 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
132
solenberg22818a52017-03-16 01:20:23 -0700133 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
solenberg76377c52017-02-21 00:54:31 -0800134 EXPECT_TRUE(gc->is_enabled());
135 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
136#else
137 EXPECT_CALL(*helper.adm(), SetAGC(false)).WillOnce(testing::Return(0));
solenberg22818a52017-03-16 01:20:23 -0700138 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false);
solenberg76377c52017-02-21 00:54:31 -0800139 EXPECT_FALSE(gc->is_enabled());
140 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
141
142 EXPECT_CALL(*helper.adm(), SetAGC(true)).WillOnce(testing::Return(0));
solenberg22818a52017-03-16 01:20:23 -0700143 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
solenberg76377c52017-02-21 00:54:31 -0800144 EXPECT_TRUE(gc->is_enabled());
145 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
146#endif
147}
148
149TEST(ApmHelpersTest, EcStatus_DefaultMode) {
150 TestHelper helper;
151 EchoCancellation* ec = helper.apm()->echo_cancellation();
152 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
153 EXPECT_FALSE(ec->is_enabled());
154 EXPECT_FALSE(ecm->is_enabled());
155}
156
157TEST(ApmHelpersTest, EcStatus_EnableDisable) {
158 TestHelper helper;
159 EchoCancellation* ec = helper.apm()->echo_cancellation();
160 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
161
162 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
163 EXPECT_FALSE(ec->is_enabled());
164 EXPECT_TRUE(ecm->is_enabled());
165
166 apm_helpers::SetEcStatus(helper.apm(), false, kEcAecm);
167 EXPECT_FALSE(ec->is_enabled());
168 EXPECT_FALSE(ecm->is_enabled());
169
170 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
171 EXPECT_TRUE(ec->is_enabled());
172 EXPECT_FALSE(ecm->is_enabled());
173 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
174
175 apm_helpers::SetEcStatus(helper.apm(), false, kEcConference);
176 EXPECT_FALSE(ec->is_enabled());
177 EXPECT_FALSE(ecm->is_enabled());
178 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
179
180 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
181 EXPECT_FALSE(ec->is_enabled());
182 EXPECT_TRUE(ecm->is_enabled());
183}
184
185TEST(ApmHelpersTest, EcMetrics_DefaultMode) {
186 TestHelper helper;
187 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
188 EXPECT_TRUE(helper.GetEcMetricsStatus());
189}
190
191TEST(ApmHelpersTest, EcMetrics_CanEnableDisable) {
192 TestHelper helper;
193 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
194
195 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
196 EXPECT_TRUE(helper.GetEcMetricsStatus());
197 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
198 EXPECT_FALSE(helper.GetEcMetricsStatus());
199}
200
201TEST(ApmHelpersTest, EcMetrics_NoStatsUnlessEcMetricsAndEcEnabled) {
202 TestHelper helper;
203 EXPECT_FALSE(helper.CanGetEcMetrics());
204
205 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
206 EXPECT_FALSE(helper.CanGetEcMetrics());
207
208 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
209 EXPECT_TRUE(helper.CanGetEcMetrics());
210
211 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
212 EXPECT_FALSE(helper.CanGetEcMetrics());
213}
214
215TEST(ApmHelpersTest, AecmMode_DefaultMode) {
216 TestHelper helper;
217 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
218 EXPECT_EQ(EchoControlMobile::kSpeakerphone, ecm->routing_mode());
219 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
220}
221
222TEST(ApmHelpersTest, AecmMode_EnableDisableCng) {
223 TestHelper helper;
224 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
225 apm_helpers::SetAecmMode(helper.apm(), false);
226 EXPECT_FALSE(ecm->is_comfort_noise_enabled());
227 apm_helpers::SetAecmMode(helper.apm(), true);
228 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
229}
230
231TEST(ApmHelpersTest, NsStatus_DefaultMode) {
232 TestHelper helper;
233 NoiseSuppression* ns = helper.apm()->noise_suppression();
234 EXPECT_EQ(NoiseSuppression::kModerate, ns->level());
235 EXPECT_FALSE(ns->is_enabled());
236}
237
238TEST(ApmHelpersTest, NsStatus_EnableDisable) {
239 TestHelper helper;
240 NoiseSuppression* ns = helper.apm()->noise_suppression();
241 apm_helpers::SetNsStatus(helper.apm(), true);
242 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
243 EXPECT_TRUE(ns->is_enabled());
244 apm_helpers::SetNsStatus(helper.apm(), false);
245 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
246 EXPECT_FALSE(ns->is_enabled());
247}
248
249TEST(ApmHelpersTest, TypingDetectionStatus_DefaultMode) {
250 TestHelper helper;
251 VoiceDetection* vd = helper.apm()->voice_detection();
252 EXPECT_FALSE(vd->is_enabled());
253}
254
oprypin45197522017-06-22 01:47:20 -0700255// TODO(kthelgason): Reenable this test on simulator.
256// See bugs.webrtc.org/5569
257#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
258#define MAYBE_TypingDetectionStatus_EnableDisable DISABLED_TypingDetectionStatus_EnableDisable
259#else
260#define MAYBE_TypingDetectionStatus_EnableDisable TypingDetectionStatus_EnableDisable
261#endif
262TEST(ApmHelpersTest, MAYBE_TypingDetectionStatus_EnableDisable) {
solenberg76377c52017-02-21 00:54:31 -0800263 TestHelper helper;
264 VoiceDetection* vd = helper.apm()->voice_detection();
265 apm_helpers::SetTypingDetectionStatus(helper.apm(), true);
266 EXPECT_TRUE(vd->is_enabled());
267 apm_helpers::SetTypingDetectionStatus(helper.apm(), false);
268 EXPECT_FALSE(vd->is_enabled());
269}
270
271// TODO(solenberg): Move this test to a better place - added here for the sake
272// of duplicating all relevant tests from audio_processing_test.cc.
273TEST(ApmHelpersTest, HighPassFilter_DefaultMode) {
274 TestHelper helper;
275 EXPECT_TRUE(helper.apm()->high_pass_filter()->is_enabled());
276}
277
278// TODO(solenberg): Move this test to a better place - added here for the sake
279// of duplicating all relevant tests from audio_processing_test.cc.
280TEST(ApmHelpersTest, StereoSwapping_DefaultMode) {
281 TestHelper helper;
282 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
283}
284
285// TODO(solenberg): Move this test to a better place - added here for the sake
286// of duplicating all relevant tests from audio_processing_test.cc.
287TEST(ApmHelpersTest, StereoSwapping_EnableDisable) {
288 TestHelper helper;
289 helper.transmit_mixer()->EnableStereoChannelSwapping(true);
290 EXPECT_TRUE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
291 helper.transmit_mixer()->EnableStereoChannelSwapping(false);
292 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
293}
294} // namespace webrtc