blob: ff9308a47e330acf51025b801737ce6e341e0ac4 [file] [log] [blame]
solenberg76377c52017-02-21 08:54:311/*
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 04:47:3111#include "media/engine/apm_helpers.h"
solenberg76377c52017-02-21 08:54:3112
Mirko Bonadei92ea95e2017-09-15 04:47:3113#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 08:54:3120
21namespace webrtc {
22namespace {
23
24constexpr AgcConfig kDefaultAgcConfig = { 3, 9, true };
25
26struct TestHelper {
27 TestHelper() {
solenberg76377c52017-02-21 08:54:3128 // This replicates the conditions from voe_auto_test.
29 Config config;
30 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
peaha9cc40b2017-06-29 15:32:0931 apm_ = rtc::scoped_refptr<AudioProcessing>(AudioProcessing::Create(config));
solenberg76377c52017-02-21 08:54:3132 EXPECT_EQ(0, voe_wrapper_.base()->Init(
peaha9cc40b2017-06-29 15:32:0933 &mock_audio_device_, apm_,
34 MockAudioDecoderFactory::CreateEmptyFactory()));
solenberg76377c52017-02-21 08:54:3135 }
36
peaha9cc40b2017-06-29 15:32:0937 AudioProcessing* apm() { return apm_.get(); }
solenberg76377c52017-02-21 08:54:3138
peaha9cc40b2017-06-29 15:32:0939 const AudioProcessing* apm() const { return apm_.get(); }
solenberg76377c52017-02-21 08:54:3140
41 test::MockAudioDeviceModule* adm() {
42 return &mock_audio_device_;
43 }
44
45 voe::TransmitMixer* transmit_mixer() {
46 return voe_wrapper_.base()->transmit_mixer();
47 }
48
49 bool GetEcMetricsStatus() const {
50 EchoCancellation* ec = apm()->echo_cancellation();
51 bool metrics_enabled = ec->are_metrics_enabled();
52 EXPECT_EQ(metrics_enabled, ec->is_delay_logging_enabled());
53 return metrics_enabled;
54 }
55
56 bool CanGetEcMetrics() const {
57 EchoCancellation* ec = apm()->echo_cancellation();
58 EchoCancellation::Metrics metrics;
59 int metrics_result = ec->GetMetrics(&metrics);
60 int median = 0;
61 int std = 0;
62 float fraction = 0;
63 int delay_metrics_result = ec->GetDelayMetrics(&median, &std, &fraction);
64 return metrics_result == AudioProcessing::kNoError &&
65 delay_metrics_result == AudioProcessing::kNoError;
66 }
67
68 private:
69 testing::NiceMock<test::MockAudioDeviceModule> mock_audio_device_;
70 cricket::VoEWrapper voe_wrapper_;
peaha9cc40b2017-06-29 15:32:0971 rtc::scoped_refptr<AudioProcessing> apm_;
solenberg76377c52017-02-21 08:54:3172};
73} // namespace
74
75TEST(ApmHelpersTest, AgcConfig_DefaultConfiguration) {
76 TestHelper helper;
77 AgcConfig agc_config =
78 apm_helpers::GetAgcConfig(helper.apm());
79
80 EXPECT_EQ(kDefaultAgcConfig.targetLeveldBOv, agc_config.targetLeveldBOv);
81 EXPECT_EQ(kDefaultAgcConfig.digitalCompressionGaindB,
82 agc_config.digitalCompressionGaindB);
83 EXPECT_EQ(kDefaultAgcConfig.limiterEnable, agc_config.limiterEnable);
84}
85
86TEST(ApmHelpersTest, AgcConfig_GetAndSet) {
87 const AgcConfig agc_config = { 11, 17, false };
88
89 TestHelper helper;
90 apm_helpers::SetAgcConfig(helper.apm(), agc_config);
91 AgcConfig actual_config =
92 apm_helpers::GetAgcConfig(helper.apm());
93
94 EXPECT_EQ(agc_config.digitalCompressionGaindB,
95 actual_config.digitalCompressionGaindB);
96 EXPECT_EQ(agc_config.limiterEnable,
97 actual_config.limiterEnable);
98 EXPECT_EQ(agc_config.targetLeveldBOv,
99 actual_config.targetLeveldBOv);
100}
101
102TEST(ApmHelpersTest, AgcStatus_DefaultMode) {
103 TestHelper helper;
104 GainControl* gc = helper.apm()->gain_control();
oprypin45197522017-06-22 08:47:20105#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
106 EXPECT_FALSE(gc->is_enabled());
107 EXPECT_EQ(GainControl::kAdaptiveDigital, gc->mode());
108#elif defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
solenberg76377c52017-02-21 08:54:31109 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)
solenberg22818a52017-03-16 08:20:23121 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false);
solenberg76377c52017-02-21 08:54:31122 EXPECT_FALSE(gc->is_enabled());
123 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
124
solenberg22818a52017-03-16 08:20:23125 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
solenberg76377c52017-02-21 08:54:31126 EXPECT_TRUE(gc->is_enabled());
127 EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
128#else
129 EXPECT_CALL(*helper.adm(), SetAGC(false)).WillOnce(testing::Return(0));
solenberg22818a52017-03-16 08:20:23130 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false);
solenberg76377c52017-02-21 08:54:31131 EXPECT_FALSE(gc->is_enabled());
132 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
133
134 EXPECT_CALL(*helper.adm(), SetAGC(true)).WillOnce(testing::Return(0));
solenberg22818a52017-03-16 08:20:23135 apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
solenberg76377c52017-02-21 08:54:31136 EXPECT_TRUE(gc->is_enabled());
137 EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
138#endif
139}
140
141TEST(ApmHelpersTest, EcStatus_DefaultMode) {
142 TestHelper helper;
143 EchoCancellation* ec = helper.apm()->echo_cancellation();
144 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
145 EXPECT_FALSE(ec->is_enabled());
146 EXPECT_FALSE(ecm->is_enabled());
147}
148
149TEST(ApmHelpersTest, EcStatus_EnableDisable) {
150 TestHelper helper;
151 EchoCancellation* ec = helper.apm()->echo_cancellation();
152 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
153
154 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
155 EXPECT_FALSE(ec->is_enabled());
156 EXPECT_TRUE(ecm->is_enabled());
157
158 apm_helpers::SetEcStatus(helper.apm(), false, kEcAecm);
159 EXPECT_FALSE(ec->is_enabled());
160 EXPECT_FALSE(ecm->is_enabled());
161
162 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
163 EXPECT_TRUE(ec->is_enabled());
164 EXPECT_FALSE(ecm->is_enabled());
165 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
166
167 apm_helpers::SetEcStatus(helper.apm(), false, kEcConference);
168 EXPECT_FALSE(ec->is_enabled());
169 EXPECT_FALSE(ecm->is_enabled());
170 EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());
171
172 apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
173 EXPECT_FALSE(ec->is_enabled());
174 EXPECT_TRUE(ecm->is_enabled());
175}
176
177TEST(ApmHelpersTest, EcMetrics_DefaultMode) {
178 TestHelper helper;
179 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
180 EXPECT_TRUE(helper.GetEcMetricsStatus());
181}
182
183TEST(ApmHelpersTest, EcMetrics_CanEnableDisable) {
184 TestHelper helper;
185 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
186
187 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
188 EXPECT_TRUE(helper.GetEcMetricsStatus());
189 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
190 EXPECT_FALSE(helper.GetEcMetricsStatus());
191}
192
193TEST(ApmHelpersTest, EcMetrics_NoStatsUnlessEcMetricsAndEcEnabled) {
194 TestHelper helper;
195 EXPECT_FALSE(helper.CanGetEcMetrics());
196
197 apm_helpers::SetEcMetricsStatus(helper.apm(), true);
198 EXPECT_FALSE(helper.CanGetEcMetrics());
199
200 apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
201 EXPECT_TRUE(helper.CanGetEcMetrics());
202
203 apm_helpers::SetEcMetricsStatus(helper.apm(), false);
204 EXPECT_FALSE(helper.CanGetEcMetrics());
205}
206
207TEST(ApmHelpersTest, AecmMode_DefaultMode) {
208 TestHelper helper;
209 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
210 EXPECT_EQ(EchoControlMobile::kSpeakerphone, ecm->routing_mode());
211 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
212}
213
214TEST(ApmHelpersTest, AecmMode_EnableDisableCng) {
215 TestHelper helper;
216 EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
217 apm_helpers::SetAecmMode(helper.apm(), false);
218 EXPECT_FALSE(ecm->is_comfort_noise_enabled());
219 apm_helpers::SetAecmMode(helper.apm(), true);
220 EXPECT_TRUE(ecm->is_comfort_noise_enabled());
221}
222
223TEST(ApmHelpersTest, NsStatus_DefaultMode) {
224 TestHelper helper;
225 NoiseSuppression* ns = helper.apm()->noise_suppression();
226 EXPECT_EQ(NoiseSuppression::kModerate, ns->level());
227 EXPECT_FALSE(ns->is_enabled());
228}
229
230TEST(ApmHelpersTest, NsStatus_EnableDisable) {
231 TestHelper helper;
232 NoiseSuppression* ns = helper.apm()->noise_suppression();
233 apm_helpers::SetNsStatus(helper.apm(), true);
234 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
235 EXPECT_TRUE(ns->is_enabled());
236 apm_helpers::SetNsStatus(helper.apm(), false);
237 EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
238 EXPECT_FALSE(ns->is_enabled());
239}
240
241TEST(ApmHelpersTest, TypingDetectionStatus_DefaultMode) {
242 TestHelper helper;
243 VoiceDetection* vd = helper.apm()->voice_detection();
244 EXPECT_FALSE(vd->is_enabled());
245}
246
oprypin45197522017-06-22 08:47:20247// TODO(kthelgason): Reenable this test on simulator.
248// See bugs.webrtc.org/5569
249#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
250#define MAYBE_TypingDetectionStatus_EnableDisable DISABLED_TypingDetectionStatus_EnableDisable
251#else
252#define MAYBE_TypingDetectionStatus_EnableDisable TypingDetectionStatus_EnableDisable
253#endif
254TEST(ApmHelpersTest, MAYBE_TypingDetectionStatus_EnableDisable) {
solenberg76377c52017-02-21 08:54:31255 TestHelper helper;
256 VoiceDetection* vd = helper.apm()->voice_detection();
257 apm_helpers::SetTypingDetectionStatus(helper.apm(), true);
258 EXPECT_TRUE(vd->is_enabled());
259 apm_helpers::SetTypingDetectionStatus(helper.apm(), false);
260 EXPECT_FALSE(vd->is_enabled());
261}
262
263// TODO(solenberg): Move this test to a better place - added here for the sake
264// of duplicating all relevant tests from audio_processing_test.cc.
265TEST(ApmHelpersTest, HighPassFilter_DefaultMode) {
266 TestHelper helper;
267 EXPECT_TRUE(helper.apm()->high_pass_filter()->is_enabled());
268}
269
270// TODO(solenberg): Move this test to a better place - added here for the sake
271// of duplicating all relevant tests from audio_processing_test.cc.
272TEST(ApmHelpersTest, StereoSwapping_DefaultMode) {
273 TestHelper helper;
274 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
275}
276
277// TODO(solenberg): Move this test to a better place - added here for the sake
278// of duplicating all relevant tests from audio_processing_test.cc.
279TEST(ApmHelpersTest, StereoSwapping_EnableDisable) {
280 TestHelper helper;
281 helper.transmit_mixer()->EnableStereoChannelSwapping(true);
282 EXPECT_TRUE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
283 helper.transmit_mixer()->EnableStereoChannelSwapping(false);
284 EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
285}
286} // namespace webrtc