blob: a86990301c9623041e590a70434098098bfa8b4f [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));
peaha9cc40b2017-06-29 08:32:09 -070036 apm_ = rtc::scoped_refptr<AudioProcessing>(AudioProcessing::Create(config));
solenberg76377c52017-02-21 00:54:31 -080037 EXPECT_EQ(0, voe_wrapper_.base()->Init(
peaha9cc40b2017-06-29 08:32:09 -070038 &mock_audio_device_, apm_,
39 MockAudioDecoderFactory::CreateEmptyFactory()));
solenberg76377c52017-02-21 00:54:31 -080040 }
41
peaha9cc40b2017-06-29 08:32:09 -070042 AudioProcessing* apm() { return apm_.get(); }
solenberg76377c52017-02-21 00:54:31 -080043
peaha9cc40b2017-06-29 08:32:09 -070044 const AudioProcessing* apm() const { return apm_.get(); }
solenberg76377c52017-02-21 00:54:31 -080045
46 test::MockAudioDeviceModule* adm() {
47 return &mock_audio_device_;
48 }
49
50 voe::TransmitMixer* transmit_mixer() {
51 return voe_wrapper_.base()->transmit_mixer();
52 }
53
54 bool GetEcMetricsStatus() const {
55 EchoCancellation* ec = apm()->echo_cancellation();
56 bool metrics_enabled = ec->are_metrics_enabled();
57 EXPECT_EQ(metrics_enabled, ec->is_delay_logging_enabled());
58 return metrics_enabled;
59 }
60
61 bool CanGetEcMetrics() const {
62 EchoCancellation* ec = apm()->echo_cancellation();
63 EchoCancellation::Metrics metrics;
64 int metrics_result = ec->GetMetrics(&metrics);
65 int median = 0;
66 int std = 0;
67 float fraction = 0;
68 int delay_metrics_result = ec->GetDelayMetrics(&median, &std, &fraction);
69 return metrics_result == AudioProcessing::kNoError &&
70 delay_metrics_result == AudioProcessing::kNoError;
71 }
72
73 private:
74 testing::NiceMock<test::MockAudioDeviceModule> mock_audio_device_;
75 cricket::VoEWrapper voe_wrapper_;
peaha9cc40b2017-06-29 08:32:09 -070076 rtc::scoped_refptr<AudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -080077};
78} // namespace
79
80TEST(ApmHelpersTest, AgcConfig_DefaultConfiguration) {
81 TestHelper helper;
82 AgcConfig agc_config =
83 apm_helpers::GetAgcConfig(helper.apm());
84
85 EXPECT_EQ(kDefaultAgcConfig.targetLeveldBOv, agc_config.targetLeveldBOv);
86 EXPECT_EQ(kDefaultAgcConfig.digitalCompressionGaindB,
87 agc_config.digitalCompressionGaindB);
88 EXPECT_EQ(kDefaultAgcConfig.limiterEnable, agc_config.limiterEnable);
89}
90
91TEST(ApmHelpersTest, AgcConfig_GetAndSet) {
92 const AgcConfig agc_config = { 11, 17, false };
93
94 TestHelper helper;
95 apm_helpers::SetAgcConfig(helper.apm(), agc_config);
96 AgcConfig actual_config =
97 apm_helpers::GetAgcConfig(helper.apm());
98
99 EXPECT_EQ(agc_config.digitalCompressionGaindB,
100 actual_config.digitalCompressionGaindB);
101 EXPECT_EQ(agc_config.limiterEnable,
102 actual_config.limiterEnable);
103 EXPECT_EQ(agc_config.targetLeveldBOv,
104 actual_config.targetLeveldBOv);
105}
106
107TEST(ApmHelpersTest, AgcStatus_DefaultMode) {
108 TestHelper helper;
109 GainControl* gc = helper.apm()->gain_control();
oprypin45197522017-06-22 01:47:20 -0700110#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
111 EXPECT_FALSE(gc->is_enabled());
112 EXPECT_EQ(GainControl::kAdaptiveDigital, gc->mode());
113#elif defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
solenberg76377c52017-02-21 00:54:31 -0800114 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
oprypin45197522017-06-22 01:47:20 -0700252// TODO(kthelgason): Reenable this test on simulator.
253// See bugs.webrtc.org/5569
254#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
255#define MAYBE_TypingDetectionStatus_EnableDisable DISABLED_TypingDetectionStatus_EnableDisable
256#else
257#define MAYBE_TypingDetectionStatus_EnableDisable TypingDetectionStatus_EnableDisable
258#endif
259TEST(ApmHelpersTest, MAYBE_TypingDetectionStatus_EnableDisable) {
solenberg76377c52017-02-21 00:54:31 -0800260 TestHelper helper;
261 VoiceDetection* vd = helper.apm()->voice_detection();
262 apm_helpers::SetTypingDetectionStatus(helper.apm(), true);
263 EXPECT_TRUE(vd->is_enabled());
264 apm_helpers::SetTypingDetectionStatus(helper.apm(), false);
265 EXPECT_FALSE(vd->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, HighPassFilter_DefaultMode) {
271 TestHelper helper;
272 EXPECT_TRUE(helper.apm()->high_pass_filter()->is_enabled());
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_DefaultMode) {
278 TestHelper helper;
279 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
280}
281
282// TODO(solenberg): Move this test to a better place - added here for the sake
283// of duplicating all relevant tests from audio_processing_test.cc.
284TEST(ApmHelpersTest, StereoSwapping_EnableDisable) {
285 TestHelper helper;
286 helper.transmit_mixer()->EnableStereoChannelSwapping(true);
287 EXPECT_TRUE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
288 helper.transmit_mixer()->EnableStereoChannelSwapping(false);
289 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
290}
291} // namespace webrtc