2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/test/testsupport/fileutils.h"
12 #include "webrtc/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h"
13 #include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"
15 class RxCallback : public webrtc::VoERxVadCallback {
21 virtual void OnRxVad(int, int vadDecision) {
23 sprintf(msg, "RX VAD detected decision %d \n", vadDecision);
25 vad_decision = vadDecision;
31 class AudioProcessingTest : public AfterStreamingFixture {
33 // Note: Be careful with this one, it is used in the
34 // Android / iPhone part too.
35 void TryEnablingAgcWithMode(webrtc::AgcModes agc_mode_to_set) {
36 EXPECT_EQ(0, voe_apm_->SetAgcStatus(true, agc_mode_to_set));
38 bool agc_enabled = false;
39 webrtc::AgcModes agc_mode = webrtc::kAgcDefault;
41 EXPECT_EQ(0, voe_apm_->GetAgcStatus(agc_enabled, agc_mode));
42 EXPECT_TRUE(agc_enabled);
43 EXPECT_EQ(agc_mode_to_set, agc_mode);
46 void TryEnablingRxAgcWithMode(webrtc::AgcModes agc_mode_to_set) {
47 EXPECT_EQ(0, voe_apm_->SetRxAgcStatus(channel_, true, agc_mode_to_set));
49 bool rx_agc_enabled = false;
50 webrtc::AgcModes agc_mode = webrtc::kAgcDefault;
52 EXPECT_EQ(0, voe_apm_->GetRxAgcStatus(channel_, rx_agc_enabled, agc_mode));
53 EXPECT_TRUE(rx_agc_enabled);
54 EXPECT_EQ(agc_mode_to_set, agc_mode);
57 // EC modes can map to other EC modes, so we have a separate parameter
58 // for what we expect the EC mode to be set to.
59 void TryEnablingEcWithMode(webrtc::EcModes ec_mode_to_set,
60 webrtc::EcModes expected_mode) {
61 EXPECT_EQ(0, voe_apm_->SetEcStatus(true, ec_mode_to_set));
63 bool ec_enabled = true;
64 webrtc::EcModes ec_mode = webrtc::kEcDefault;
66 EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
68 EXPECT_EQ(expected_mode, ec_mode);
71 // Here, the CNG mode will be expected to be on or off depending on the mode.
72 void TryEnablingAecmWithMode(webrtc::AecmModes aecm_mode_to_set,
73 bool cng_enabled_to_set) {
74 EXPECT_EQ(0, voe_apm_->SetAecmMode(aecm_mode_to_set, cng_enabled_to_set));
76 bool cng_enabled = false;
77 webrtc::AecmModes aecm_mode = webrtc::kAecmEarpiece;
79 voe_apm_->GetAecmMode(aecm_mode, cng_enabled);
81 EXPECT_EQ(cng_enabled_to_set, cng_enabled);
82 EXPECT_EQ(aecm_mode_to_set, aecm_mode);
85 void TryEnablingNsWithMode(webrtc::NsModes ns_mode_to_set,
86 webrtc::NsModes expected_ns_mode) {
87 EXPECT_EQ(0, voe_apm_->SetNsStatus(true, ns_mode_to_set));
89 bool ns_status = true;
90 webrtc::NsModes ns_mode = webrtc::kNsDefault;
91 EXPECT_EQ(0, voe_apm_->GetNsStatus(ns_status, ns_mode));
93 EXPECT_TRUE(ns_status);
94 EXPECT_EQ(expected_ns_mode, ns_mode);
97 void TryEnablingRxNsWithMode(webrtc::NsModes ns_mode_to_set,
98 webrtc::NsModes expected_ns_mode) {
99 EXPECT_EQ(0, voe_apm_->SetRxNsStatus(channel_, true, ns_mode_to_set));
101 bool ns_status = true;
102 webrtc::NsModes ns_mode = webrtc::kNsDefault;
103 EXPECT_EQ(0, voe_apm_->GetRxNsStatus(channel_, ns_status, ns_mode));
105 EXPECT_TRUE(ns_status);
106 EXPECT_EQ(expected_ns_mode, ns_mode);
109 void TryDetectingSilence() {
110 // Here, speech is running. Shut down speech.
111 EXPECT_EQ(0, voe_codec_->SetVADStatus(channel_, true));
112 EXPECT_EQ(0, voe_volume_control_->SetInputMute(channel_, true));
113 EXPECT_EQ(0, voe_file_->StopPlayingFileAsMicrophone(channel_));
115 // We should detect the silence after a short time.
117 for (int i = 0; i < 25; i++) {
118 EXPECT_EQ(0, voe_apm_->VoiceActivityIndicator(channel_));
123 void TryDetectingSpeechAfterSilence() {
125 RestartFakeMicrophone();
126 EXPECT_EQ(0, voe_codec_->SetVADStatus(channel_, false));
127 EXPECT_EQ(0, voe_volume_control_->SetInputMute(channel_, false));
129 // We should detect the speech after a short time.
130 for (int i = 0; i < 50; i++) {
131 if (voe_apm_->VoiceActivityIndicator(channel_) == 1) {
137 ADD_FAILURE() << "Failed to detect speech within 500 ms.";
141 #if !defined(WEBRTC_IOS) && !defined(WEBRTC_ANDROID)
143 TEST_F(AudioProcessingTest, AgcIsOnByDefault) {
144 bool agc_enabled = false;
145 webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog;
147 EXPECT_EQ(0, voe_apm_->GetAgcStatus(agc_enabled, agc_mode));
148 EXPECT_TRUE(agc_enabled);
149 EXPECT_EQ(webrtc::kAgcAdaptiveAnalog, agc_mode);
152 TEST_F(AudioProcessingTest, CanEnableAgcWithAllModes) {
153 TryEnablingAgcWithMode(webrtc::kAgcAdaptiveDigital);
154 TryEnablingAgcWithMode(webrtc::kAgcAdaptiveAnalog);
155 TryEnablingAgcWithMode(webrtc::kAgcFixedDigital);
158 TEST_F(AudioProcessingTest, EcIsDisabledAndAecIsDefaultEcMode) {
159 bool ec_enabled = true;
160 webrtc::EcModes ec_mode = webrtc::kEcDefault;
162 EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
163 EXPECT_FALSE(ec_enabled);
164 EXPECT_EQ(webrtc::kEcAec, ec_mode);
167 TEST_F(AudioProcessingTest, EnablingEcAecShouldEnableEcAec) {
168 TryEnablingEcWithMode(webrtc::kEcAec, webrtc::kEcAec);
171 TEST_F(AudioProcessingTest, EnablingEcConferenceShouldEnableEcAec) {
172 TryEnablingEcWithMode(webrtc::kEcConference, webrtc::kEcAec);
175 TEST_F(AudioProcessingTest, EcModeIsPreservedWhenEcIsTurnedOff) {
176 TryEnablingEcWithMode(webrtc::kEcConference, webrtc::kEcAec);
178 EXPECT_EQ(0, voe_apm_->SetEcStatus(false));
180 bool ec_enabled = true;
181 webrtc::EcModes ec_mode = webrtc::kEcDefault;
182 EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
184 EXPECT_FALSE(ec_enabled);
185 EXPECT_EQ(webrtc::kEcAec, ec_mode);
188 TEST_F(AudioProcessingTest, CanEnableAndDisableEcModeSeveralTimesInARow) {
189 for (int i = 0; i < 10; i++) {
190 EXPECT_EQ(0, voe_apm_->SetEcStatus(true));
191 EXPECT_EQ(0, voe_apm_->SetEcStatus(false));
194 bool ec_enabled = true;
195 webrtc::EcModes ec_mode = webrtc::kEcDefault;
196 EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
198 EXPECT_FALSE(ec_enabled);
199 EXPECT_EQ(webrtc::kEcAec, ec_mode);
202 // TODO(phoglund): Reenable below test when it's no longer flaky.
203 TEST_F(AudioProcessingTest, DISABLED_TestVoiceActivityDetectionWithObserver) {
204 RxCallback rx_callback;
205 EXPECT_EQ(0, voe_apm_->RegisterRxVadObserver(channel_, rx_callback));
207 // The extra sleeps are to allow decisions some time to propagate to the
209 TryDetectingSilence();
212 EXPECT_EQ(0, rx_callback.vad_decision);
214 TryDetectingSpeechAfterSilence();
217 EXPECT_EQ(1, rx_callback.vad_decision);
219 EXPECT_EQ(0, voe_apm_->DeRegisterRxVadObserver(channel_));
222 #endif // !WEBRTC_IOS && !WEBRTC_ANDROID
224 TEST_F(AudioProcessingTest, EnablingEcAecmShouldEnableEcAecm) {
225 // This one apparently applies to Android and iPhone as well.
226 TryEnablingEcWithMode(webrtc::kEcAecm, webrtc::kEcAecm);
229 TEST_F(AudioProcessingTest, EcAecmModeIsEnabledAndSpeakerphoneByDefault) {
230 bool cng_enabled = false;
231 webrtc::AecmModes aecm_mode = webrtc::kAecmEarpiece;
233 voe_apm_->GetAecmMode(aecm_mode, cng_enabled);
235 EXPECT_TRUE(cng_enabled);
236 EXPECT_EQ(webrtc::kAecmSpeakerphone, aecm_mode);
239 TEST_F(AudioProcessingTest, CanSetAecmMode) {
240 EXPECT_EQ(0, voe_apm_->SetEcStatus(true, webrtc::kEcAecm));
242 // Try some AECM mode - CNG enabled combinations.
243 TryEnablingAecmWithMode(webrtc::kAecmEarpiece, true);
244 TryEnablingAecmWithMode(webrtc::kAecmEarpiece, false);
245 TryEnablingAecmWithMode(webrtc::kAecmLoudEarpiece, true);
246 TryEnablingAecmWithMode(webrtc::kAecmLoudSpeakerphone, false);
247 TryEnablingAecmWithMode(webrtc::kAecmQuietEarpieceOrHeadset, true);
248 TryEnablingAecmWithMode(webrtc::kAecmSpeakerphone, false);
251 TEST_F(AudioProcessingTest, RxAgcShouldBeOffByDefault) {
252 bool rx_agc_enabled = true;
253 webrtc::AgcModes agc_mode = webrtc::kAgcDefault;
255 EXPECT_EQ(0, voe_apm_->GetRxAgcStatus(channel_, rx_agc_enabled, agc_mode));
256 EXPECT_FALSE(rx_agc_enabled);
257 EXPECT_EQ(webrtc::kAgcAdaptiveDigital, agc_mode);
260 TEST_F(AudioProcessingTest, CanTurnOnDigitalRxAcg) {
261 TryEnablingRxAgcWithMode(webrtc::kAgcAdaptiveDigital);
262 TryEnablingRxAgcWithMode(webrtc::kAgcFixedDigital);
265 TEST_F(AudioProcessingTest, CannotTurnOnAdaptiveAnalogRxAgc) {
266 EXPECT_EQ(-1, voe_apm_->SetRxAgcStatus(
267 channel_, true, webrtc::kAgcAdaptiveAnalog));
270 TEST_F(AudioProcessingTest, NsIsOffWithModerateSuppressionByDefault) {
271 bool ns_status = true;
272 webrtc::NsModes ns_mode = webrtc::kNsDefault;
273 EXPECT_EQ(0, voe_apm_->GetNsStatus(ns_status, ns_mode));
275 EXPECT_FALSE(ns_status);
276 EXPECT_EQ(webrtc::kNsModerateSuppression, ns_mode);
279 TEST_F(AudioProcessingTest, CanSetNsMode) {
280 // Concrete suppression values map to themselves.
281 TryEnablingNsWithMode(webrtc::kNsHighSuppression,
282 webrtc::kNsHighSuppression);
283 TryEnablingNsWithMode(webrtc::kNsLowSuppression,
284 webrtc::kNsLowSuppression);
285 TryEnablingNsWithMode(webrtc::kNsModerateSuppression,
286 webrtc::kNsModerateSuppression);
287 TryEnablingNsWithMode(webrtc::kNsVeryHighSuppression,
288 webrtc::kNsVeryHighSuppression);
290 // Conference and Default map to concrete values.
291 TryEnablingNsWithMode(webrtc::kNsConference,
292 webrtc::kNsHighSuppression);
293 TryEnablingNsWithMode(webrtc::kNsDefault,
294 webrtc::kNsModerateSuppression);
297 TEST_F(AudioProcessingTest, RxNsIsOffWithModerateSuppressionByDefault) {
298 bool ns_status = true;
299 webrtc::NsModes ns_mode = webrtc::kNsDefault;
300 EXPECT_EQ(0, voe_apm_->GetRxNsStatus(channel_, ns_status, ns_mode));
302 EXPECT_FALSE(ns_status);
303 EXPECT_EQ(webrtc::kNsModerateSuppression, ns_mode);
306 TEST_F(AudioProcessingTest, CanSetRxNsMode) {
307 EXPECT_EQ(0, voe_apm_->SetRxNsStatus(channel_, true));
309 // See comments on the regular NS test above.
310 TryEnablingRxNsWithMode(webrtc::kNsHighSuppression,
311 webrtc::kNsHighSuppression);
312 TryEnablingRxNsWithMode(webrtc::kNsLowSuppression,
313 webrtc::kNsLowSuppression);
314 TryEnablingRxNsWithMode(webrtc::kNsModerateSuppression,
315 webrtc::kNsModerateSuppression);
316 TryEnablingRxNsWithMode(webrtc::kNsVeryHighSuppression,
317 webrtc::kNsVeryHighSuppression);
318 TryEnablingRxNsWithMode(webrtc::kNsConference,
319 webrtc::kNsHighSuppression);
320 TryEnablingRxNsWithMode(webrtc::kNsDefault,
321 webrtc::kNsModerateSuppression);
324 TEST_F(AudioProcessingTest, VadIsDisabledByDefault) {
327 webrtc::VadModes vad_mode;
329 EXPECT_EQ(0, voe_codec_->GetVADStatus(
330 channel_, vad_enabled, vad_mode, disabled_dtx));
332 EXPECT_FALSE(vad_enabled);
335 TEST_F(AudioProcessingTest, VoiceActivityIndicatorReturns1WithSpeechOn) {
336 // This sleep is necessary since the voice detection algorithm needs some
337 // time to detect the speech from the fake microphone.
339 EXPECT_EQ(1, voe_apm_->VoiceActivityIndicator(channel_));
342 TEST_F(AudioProcessingTest, CanSetDelayOffset) {
343 voe_apm_->SetDelayOffsetMs(50);
344 EXPECT_EQ(50, voe_apm_->DelayOffsetMs());
345 voe_apm_->SetDelayOffsetMs(-50);
346 EXPECT_EQ(-50, voe_apm_->DelayOffsetMs());
349 TEST_F(AudioProcessingTest, HighPassFilterIsOnByDefault) {
350 EXPECT_TRUE(voe_apm_->IsHighPassFilterEnabled());
353 TEST_F(AudioProcessingTest, CanSetHighPassFilter) {
354 EXPECT_EQ(0, voe_apm_->EnableHighPassFilter(true));
355 EXPECT_TRUE(voe_apm_->IsHighPassFilterEnabled());
356 EXPECT_EQ(0, voe_apm_->EnableHighPassFilter(false));
357 EXPECT_FALSE(voe_apm_->IsHighPassFilterEnabled());
360 TEST_F(AudioProcessingTest, StereoChannelSwappingIsOffByDefault) {
361 EXPECT_FALSE(voe_apm_->IsStereoChannelSwappingEnabled());
364 TEST_F(AudioProcessingTest, CanSetStereoChannelSwapping) {
365 voe_apm_->EnableStereoChannelSwapping(true);
366 EXPECT_TRUE(voe_apm_->IsStereoChannelSwappingEnabled());
367 voe_apm_->EnableStereoChannelSwapping(false);
368 EXPECT_FALSE(voe_apm_->IsStereoChannelSwappingEnabled());
371 TEST_F(AudioProcessingTest, CanStartAndStopDebugRecording) {
372 std::string output_path = webrtc::test::OutputPath();
373 std::string output_file = output_path + "apm_debug.txt";
375 EXPECT_EQ(0, voe_apm_->StartDebugRecording(output_file.c_str()));
377 EXPECT_EQ(0, voe_apm_->StopDebugRecording());
380 #if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
382 TEST_F(AudioProcessingTest, AgcIsOffByDefaultAndDigital) {
383 bool agc_enabled = true;
384 webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog;
386 EXPECT_EQ(0, voe_apm_->GetAgcStatus(agc_enabled, agc_mode));
387 EXPECT_FALSE(agc_enabled);
388 EXPECT_EQ(webrtc::kAgcAdaptiveDigital, agc_mode);
391 TEST_F(AudioProcessingTest, CanEnableAgcInAdaptiveDigitalMode) {
392 TryEnablingAgcWithMode(webrtc::kAgcAdaptiveDigital);
395 TEST_F(AudioProcessingTest, AgcIsPossibleExceptInAdaptiveAnalogMode) {
396 EXPECT_EQ(-1, voe_apm_->SetAgcStatus(true, webrtc::kAgcAdaptiveAnalog));
397 EXPECT_EQ(0, voe_apm_->SetAgcStatus(true, webrtc::kAgcFixedDigital));
398 EXPECT_EQ(0, voe_apm_->SetAgcStatus(true, webrtc::kAgcAdaptiveDigital));
401 TEST_F(AudioProcessingTest, EcIsDisabledAndAecmIsDefaultEcMode) {
402 bool ec_enabled = true;
403 webrtc::EcModes ec_mode = webrtc::kEcDefault;
405 EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
406 EXPECT_FALSE(ec_enabled);
407 EXPECT_EQ(webrtc::kEcAecm, ec_mode);
410 TEST_F(AudioProcessingTest, TestVoiceActivityDetection) {
411 TryDetectingSilence();
412 TryDetectingSpeechAfterSilence();
415 #endif // WEBRTC_IOS || WEBRTC_ANDROID