blob: c20eb6faff39fee9ffb446fb885df332da8ddb89 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "media/engine/apm_helpers.h"
solenberg76377c52017-02-21 00:54:31 -080012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "media/engine/webrtcvoe.h"
14#include "modules/audio_device/include/mock_audio_device.h"
15#include "modules/audio_processing/include/audio_processing.h"
16#include "test/gmock.h"
17#include "test/gtest.h"
18#include "test/mock_audio_decoder_factory.h"
19#include "voice_engine/transmit_mixer.h"
solenberg76377c52017-02-21 00:54:31 -080020
21namespace webrtc {
22namespace {
23
24constexpr AgcConfig kDefaultAgcConfig = { 3, 9, true };
25
26struct TestHelper {
27 TestHelper() {
solenberg76377c52017-02-21 00:54:31 -080028 // This replicates the conditions from voe_auto_test.
29 Config config;
30 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
peaha9cc40b2017-06-29 08:32:09 -070031 apm_ = rtc::scoped_refptr<AudioProcessing>(AudioProcessing::Create(config));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010032 apm_helpers::Init(apm());
solenberg76377c52017-02-21 00:54:31 -080033 EXPECT_EQ(0, voe_wrapper_.base()->Init(
peaha9cc40b2017-06-29 08:32:09 -070034 &mock_audio_device_, apm_,
35 MockAudioDecoderFactory::CreateEmptyFactory()));
solenberg76377c52017-02-21 00:54:31 -080036 }
37
peaha9cc40b2017-06-29 08:32:09 -070038 AudioProcessing* apm() { return apm_.get(); }
solenberg76377c52017-02-21 00:54:31 -080039
peaha9cc40b2017-06-29 08:32:09 -070040 const AudioProcessing* apm() const { return apm_.get(); }
solenberg76377c52017-02-21 00:54:31 -080041
42 test::MockAudioDeviceModule* adm() {
43 return &mock_audio_device_;
44 }
45
46 voe::TransmitMixer* transmit_mixer() {
47 return voe_wrapper_.base()->transmit_mixer();
48 }
49
50 bool GetEcMetricsStatus() const {
51 EchoCancellation* ec = apm()->echo_cancellation();
52 bool metrics_enabled = ec->are_metrics_enabled();
53 EXPECT_EQ(metrics_enabled, ec->is_delay_logging_enabled());
54 return metrics_enabled;
55 }
56
57 bool CanGetEcMetrics() const {
58 EchoCancellation* ec = apm()->echo_cancellation();
59 EchoCancellation::Metrics metrics;
60 int metrics_result = ec->GetMetrics(&metrics);
61 int median = 0;
62 int std = 0;
63 float fraction = 0;
64 int delay_metrics_result = ec->GetDelayMetrics(&median, &std, &fraction);
65 return metrics_result == AudioProcessing::kNoError &&
66 delay_metrics_result == AudioProcessing::kNoError;
67 }
68
69 private:
70 testing::NiceMock<test::MockAudioDeviceModule> mock_audio_device_;
71 cricket::VoEWrapper voe_wrapper_;
peaha9cc40b2017-06-29 08:32:09 -070072 rtc::scoped_refptr<AudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -080073};
74} // namespace
75
76TEST(ApmHelpersTest, AgcConfig_DefaultConfiguration) {
77 TestHelper helper;
78 AgcConfig agc_config =
79 apm_helpers::GetAgcConfig(helper.apm());
80
81 EXPECT_EQ(kDefaultAgcConfig.targetLeveldBOv, agc_config.targetLeveldBOv);
82 EXPECT_EQ(kDefaultAgcConfig.digitalCompressionGaindB,
83 agc_config.digitalCompressionGaindB);
84 EXPECT_EQ(kDefaultAgcConfig.limiterEnable, agc_config.limiterEnable);
85}
86
87TEST(ApmHelpersTest, AgcConfig_GetAndSet) {
88 const AgcConfig agc_config = { 11, 17, false };
89
90 TestHelper helper;
91 apm_helpers::SetAgcConfig(helper.apm(), agc_config);
92 AgcConfig actual_config =
93 apm_helpers::GetAgcConfig(helper.apm());
94
95 EXPECT_EQ(agc_config.digitalCompressionGaindB,
96 actual_config.digitalCompressionGaindB);
97 EXPECT_EQ(agc_config.limiterEnable,
98 actual_config.limiterEnable);
99 EXPECT_EQ(agc_config.targetLeveldBOv,
100 actual_config.targetLeveldBOv);
101}
102
103TEST(ApmHelpersTest, AgcStatus_DefaultMode) {
104 TestHelper helper;
105 GainControl* gc = helper.apm()->gain_control();
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100106 EXPECT_FALSE(gc->is_enabled());
oprypin45197522017-06-22 01:47:20 -0700107#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100108 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
oprypin45197522017-06-22 01:47:20 -0700109#elif defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
solenberg76377c52017-02-21 00:54:31 -0800110 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
111#else
solenberg76377c52017-02-21 00:54:31 -0800112 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
113#endif
114}
115
116TEST(ApmHelpersTest, AgcStatus_EnableDisable) {
117 TestHelper helper;
118 GainControl* gc = helper.apm()->gain_control();
119#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
solenberg22818a52017-03-16 01:20:23 -0700120 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false);
solenberg76377c52017-02-21 00:54:31 -0800121 EXPECT_FALSE(gc->is_enabled());
122 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
123
solenberg22818a52017-03-16 01:20:23 -0700124 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
solenberg76377c52017-02-21 00:54:31 -0800125 EXPECT_TRUE(gc->is_enabled());
126 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
127#else
128 EXPECT_CALL(*helper.adm(), SetAGC(false)).WillOnce(testing::Return(0));
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::kAdaptiveAnalog, gc->mode());
132
133 EXPECT_CALL(*helper.adm(), SetAGC(true)).WillOnce(testing::Return(0));
solenberg22818a52017-03-16 01:20:23 -0700134 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
solenberg76377c52017-02-21 00:54:31 -0800135 EXPECT_TRUE(gc->is_enabled());
136 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
137#endif
138}
139
140TEST(ApmHelpersTest, EcStatus_DefaultMode) {
141 TestHelper helper;
142 EchoCancellation* ec = helper.apm()->echo_cancellation();
143 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
144 EXPECT_FALSE(ec->is_enabled());
145 EXPECT_FALSE(ecm->is_enabled());
146}
147
148TEST(ApmHelpersTest, EcStatus_EnableDisable) {
149 TestHelper helper;
150 EchoCancellation* ec = helper.apm()->echo_cancellation();
151 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
152
153 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
154 EXPECT_FALSE(ec->is_enabled());
155 EXPECT_TRUE(ecm->is_enabled());
156
157 apm_helpers::SetEcStatus(helper.apm(), false, kEcAecm);
158 EXPECT_FALSE(ec->is_enabled());
159 EXPECT_FALSE(ecm->is_enabled());
160
161 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
162 EXPECT_TRUE(ec->is_enabled());
163 EXPECT_FALSE(ecm->is_enabled());
164 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
165
166 apm_helpers::SetEcStatus(helper.apm(), false, kEcConference);
167 EXPECT_FALSE(ec->is_enabled());
168 EXPECT_FALSE(ecm->is_enabled());
169 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
170
171 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
172 EXPECT_FALSE(ec->is_enabled());
173 EXPECT_TRUE(ecm->is_enabled());
174}
175
176TEST(ApmHelpersTest, EcMetrics_DefaultMode) {
177 TestHelper helper;
178 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
179 EXPECT_TRUE(helper.GetEcMetricsStatus());
180}
181
182TEST(ApmHelpersTest, EcMetrics_CanEnableDisable) {
183 TestHelper helper;
184 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
185
186 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
187 EXPECT_TRUE(helper.GetEcMetricsStatus());
188 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
189 EXPECT_FALSE(helper.GetEcMetricsStatus());
190}
191
192TEST(ApmHelpersTest, EcMetrics_NoStatsUnlessEcMetricsAndEcEnabled) {
193 TestHelper helper;
194 EXPECT_FALSE(helper.CanGetEcMetrics());
195
196 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
197 EXPECT_FALSE(helper.CanGetEcMetrics());
198
199 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
200 EXPECT_TRUE(helper.CanGetEcMetrics());
201
202 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
203 EXPECT_FALSE(helper.CanGetEcMetrics());
204}
205
206TEST(ApmHelpersTest, AecmMode_DefaultMode) {
207 TestHelper helper;
208 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
209 EXPECT_EQ(EchoControlMobile::kSpeakerphone, ecm->routing_mode());
210 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
211}
212
213TEST(ApmHelpersTest, AecmMode_EnableDisableCng) {
214 TestHelper helper;
215 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
216 apm_helpers::SetAecmMode(helper.apm(), false);
217 EXPECT_FALSE(ecm->is_comfort_noise_enabled());
218 apm_helpers::SetAecmMode(helper.apm(), true);
219 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
220}
221
222TEST(ApmHelpersTest, NsStatus_DefaultMode) {
223 TestHelper helper;
224 NoiseSuppression* ns = helper.apm()->noise_suppression();
225 EXPECT_EQ(NoiseSuppression::kModerate, ns->level());
226 EXPECT_FALSE(ns->is_enabled());
227}
228
229TEST(ApmHelpersTest, NsStatus_EnableDisable) {
230 TestHelper helper;
231 NoiseSuppression* ns = helper.apm()->noise_suppression();
232 apm_helpers::SetNsStatus(helper.apm(), true);
233 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
234 EXPECT_TRUE(ns->is_enabled());
235 apm_helpers::SetNsStatus(helper.apm(), false);
236 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
237 EXPECT_FALSE(ns->is_enabled());
238}
239
240TEST(ApmHelpersTest, TypingDetectionStatus_DefaultMode) {
241 TestHelper helper;
242 VoiceDetection* vd = helper.apm()->voice_detection();
243 EXPECT_FALSE(vd->is_enabled());
244}
245
oprypin45197522017-06-22 01:47:20 -0700246// TODO(kthelgason): Reenable this test on simulator.
247// See bugs.webrtc.org/5569
248#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
Steve Antone78bcb92017-10-31 09:53:08 -0700249#define MAYBE_TypingDetectionStatus_EnableDisable \
250 DISABLED_TypingDetectionStatus_EnableDisable
oprypin45197522017-06-22 01:47:20 -0700251#else
Steve Antone78bcb92017-10-31 09:53:08 -0700252#define MAYBE_TypingDetectionStatus_EnableDisable \
253 TypingDetectionStatus_EnableDisable
oprypin45197522017-06-22 01:47:20 -0700254#endif
255TEST(ApmHelpersTest, MAYBE_TypingDetectionStatus_EnableDisable) {
solenberg76377c52017-02-21 00:54:31 -0800256 TestHelper helper;
257 VoiceDetection* vd = helper.apm()->voice_detection();
258 apm_helpers::SetTypingDetectionStatus(helper.apm(), true);
259 EXPECT_TRUE(vd->is_enabled());
260 apm_helpers::SetTypingDetectionStatus(helper.apm(), false);
261 EXPECT_FALSE(vd->is_enabled());
262}
263
264// TODO(solenberg): Move this test to a better place - added here for the sake
265// of duplicating all relevant tests from audio_processing_test.cc.
266TEST(ApmHelpersTest, HighPassFilter_DefaultMode) {
267 TestHelper helper;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100268 EXPECT_FALSE(helper.apm()->high_pass_filter()->is_enabled());
solenberg76377c52017-02-21 00:54:31 -0800269}
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, StereoSwapping_DefaultMode) {
274 TestHelper helper;
275 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
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_EnableDisable) {
281 TestHelper helper;
282 helper.transmit_mixer()->EnableStereoChannelSwapping(true);
283 EXPECT_TRUE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
284 helper.transmit_mixer()->EnableStereoChannelSwapping(false);
285 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
286}
287} // namespace webrtc