Home | History | Annotate | Download | only in standard
      1 /*
      2  *  Copyright (c) 2012 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/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"
     14 
     15 class RxCallback : public webrtc::VoERxVadCallback {
     16  public:
     17   RxCallback() :
     18     vad_decision(-1) {
     19   }
     20 
     21   virtual void OnRxVad(int, int vadDecision) {
     22     char msg[128];
     23     sprintf(msg, "RX VAD detected decision %d \n", vadDecision);
     24     TEST_LOG("%s", msg);
     25     vad_decision = vadDecision;
     26   }
     27 
     28   int vad_decision;
     29 };
     30 
     31 class AudioProcessingTest : public AfterStreamingFixture {
     32  protected:
     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));
     37 
     38     bool agc_enabled = false;
     39     webrtc::AgcModes agc_mode = webrtc::kAgcDefault;
     40 
     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);
     44   }
     45 
     46   void TryEnablingRxAgcWithMode(webrtc::AgcModes agc_mode_to_set) {
     47     EXPECT_EQ(0, voe_apm_->SetRxAgcStatus(channel_, true, agc_mode_to_set));
     48 
     49     bool rx_agc_enabled = false;
     50     webrtc::AgcModes agc_mode = webrtc::kAgcDefault;
     51 
     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);
     55   }
     56 
     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));
     62 
     63     bool ec_enabled = true;
     64     webrtc::EcModes ec_mode = webrtc::kEcDefault;
     65 
     66     EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
     67 
     68     EXPECT_EQ(expected_mode, ec_mode);
     69   }
     70 
     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));
     75 
     76     bool cng_enabled = false;
     77     webrtc::AecmModes aecm_mode = webrtc::kAecmEarpiece;
     78 
     79     voe_apm_->GetAecmMode(aecm_mode, cng_enabled);
     80 
     81     EXPECT_EQ(cng_enabled_to_set, cng_enabled);
     82     EXPECT_EQ(aecm_mode_to_set, aecm_mode);
     83   }
     84 
     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));
     88 
     89     bool ns_status = true;
     90     webrtc::NsModes ns_mode = webrtc::kNsDefault;
     91     EXPECT_EQ(0, voe_apm_->GetNsStatus(ns_status, ns_mode));
     92 
     93     EXPECT_TRUE(ns_status);
     94     EXPECT_EQ(expected_ns_mode, ns_mode);
     95   }
     96 
     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));
    100 
    101     bool ns_status = true;
    102     webrtc::NsModes ns_mode = webrtc::kNsDefault;
    103     EXPECT_EQ(0, voe_apm_->GetRxNsStatus(channel_, ns_status, ns_mode));
    104 
    105     EXPECT_TRUE(ns_status);
    106     EXPECT_EQ(expected_ns_mode, ns_mode);
    107   }
    108 
    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_));
    114 
    115     // We should detect the silence after a short time.
    116     Sleep(50);
    117     for (int i = 0; i < 25; i++) {
    118       EXPECT_EQ(0, voe_apm_->VoiceActivityIndicator(channel_));
    119       Sleep(10);
    120     }
    121   }
    122 
    123   void TryDetectingSpeechAfterSilence() {
    124     // Re-enable speech.
    125     RestartFakeMicrophone();
    126     EXPECT_EQ(0, voe_codec_->SetVADStatus(channel_, false));
    127     EXPECT_EQ(0, voe_volume_control_->SetInputMute(channel_, false));
    128 
    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) {
    132         return;
    133       }
    134       Sleep(10);
    135     }
    136 
    137     ADD_FAILURE() << "Failed to detect speech within 500 ms.";
    138   }
    139 };
    140 
    141 #if !defined(WEBRTC_IOS) && !defined(WEBRTC_ANDROID)
    142 
    143 TEST_F(AudioProcessingTest, AgcIsOnByDefault) {
    144   bool agc_enabled = false;
    145   webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog;
    146 
    147   EXPECT_EQ(0, voe_apm_->GetAgcStatus(agc_enabled, agc_mode));
    148   EXPECT_TRUE(agc_enabled);
    149   EXPECT_EQ(webrtc::kAgcAdaptiveAnalog, agc_mode);
    150 }
    151 
    152 TEST_F(AudioProcessingTest, CanEnableAgcWithAllModes) {
    153   TryEnablingAgcWithMode(webrtc::kAgcAdaptiveDigital);
    154   TryEnablingAgcWithMode(webrtc::kAgcAdaptiveAnalog);
    155   TryEnablingAgcWithMode(webrtc::kAgcFixedDigital);
    156 }
    157 
    158 TEST_F(AudioProcessingTest, EcIsDisabledAndAecIsDefaultEcMode) {
    159   bool ec_enabled = true;
    160   webrtc::EcModes ec_mode = webrtc::kEcDefault;
    161 
    162   EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
    163   EXPECT_FALSE(ec_enabled);
    164   EXPECT_EQ(webrtc::kEcAec, ec_mode);
    165 }
    166 
    167 TEST_F(AudioProcessingTest, EnablingEcAecShouldEnableEcAec) {
    168   TryEnablingEcWithMode(webrtc::kEcAec, webrtc::kEcAec);
    169 }
    170 
    171 TEST_F(AudioProcessingTest, EnablingEcConferenceShouldEnableEcAec) {
    172   TryEnablingEcWithMode(webrtc::kEcConference, webrtc::kEcAec);
    173 }
    174 
    175 TEST_F(AudioProcessingTest, EcModeIsPreservedWhenEcIsTurnedOff) {
    176   TryEnablingEcWithMode(webrtc::kEcConference, webrtc::kEcAec);
    177 
    178   EXPECT_EQ(0, voe_apm_->SetEcStatus(false));
    179 
    180   bool ec_enabled = true;
    181   webrtc::EcModes ec_mode = webrtc::kEcDefault;
    182   EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
    183 
    184   EXPECT_FALSE(ec_enabled);
    185   EXPECT_EQ(webrtc::kEcAec, ec_mode);
    186 }
    187 
    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));
    192   }
    193 
    194   bool ec_enabled = true;
    195   webrtc::EcModes ec_mode = webrtc::kEcDefault;
    196   EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
    197 
    198   EXPECT_FALSE(ec_enabled);
    199   EXPECT_EQ(webrtc::kEcAec, ec_mode);
    200 }
    201 
    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));
    206 
    207   // The extra sleeps are to allow decisions some time to propagate to the
    208   // observer.
    209   TryDetectingSilence();
    210   Sleep(100);
    211 
    212   EXPECT_EQ(0, rx_callback.vad_decision);
    213 
    214   TryDetectingSpeechAfterSilence();
    215   Sleep(100);
    216 
    217   EXPECT_EQ(1, rx_callback.vad_decision);
    218 
    219   EXPECT_EQ(0, voe_apm_->DeRegisterRxVadObserver(channel_));
    220 }
    221 
    222 #endif   // !WEBRTC_IOS && !WEBRTC_ANDROID
    223 
    224 TEST_F(AudioProcessingTest, EnablingEcAecmShouldEnableEcAecm) {
    225   // This one apparently applies to Android and iPhone as well.
    226   TryEnablingEcWithMode(webrtc::kEcAecm, webrtc::kEcAecm);
    227 }
    228 
    229 TEST_F(AudioProcessingTest, EcAecmModeIsEnabledAndSpeakerphoneByDefault) {
    230   bool cng_enabled = false;
    231   webrtc::AecmModes aecm_mode = webrtc::kAecmEarpiece;
    232 
    233   voe_apm_->GetAecmMode(aecm_mode, cng_enabled);
    234 
    235   EXPECT_TRUE(cng_enabled);
    236   EXPECT_EQ(webrtc::kAecmSpeakerphone, aecm_mode);
    237 }
    238 
    239 TEST_F(AudioProcessingTest, CanSetAecmMode) {
    240   EXPECT_EQ(0, voe_apm_->SetEcStatus(true, webrtc::kEcAecm));
    241 
    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);
    249 }
    250 
    251 TEST_F(AudioProcessingTest, RxAgcShouldBeOffByDefault) {
    252   bool rx_agc_enabled = true;
    253   webrtc::AgcModes agc_mode = webrtc::kAgcDefault;
    254 
    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);
    258 }
    259 
    260 TEST_F(AudioProcessingTest, CanTurnOnDigitalRxAcg) {
    261   TryEnablingRxAgcWithMode(webrtc::kAgcAdaptiveDigital);
    262   TryEnablingRxAgcWithMode(webrtc::kAgcFixedDigital);
    263 }
    264 
    265 TEST_F(AudioProcessingTest, CannotTurnOnAdaptiveAnalogRxAgc) {
    266   EXPECT_EQ(-1, voe_apm_->SetRxAgcStatus(
    267       channel_, true, webrtc::kAgcAdaptiveAnalog));
    268 }
    269 
    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));
    274 
    275   EXPECT_FALSE(ns_status);
    276   EXPECT_EQ(webrtc::kNsModerateSuppression, ns_mode);
    277 }
    278 
    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);
    289 
    290   // Conference and Default map to concrete values.
    291   TryEnablingNsWithMode(webrtc::kNsConference,
    292                         webrtc::kNsHighSuppression);
    293   TryEnablingNsWithMode(webrtc::kNsDefault,
    294                         webrtc::kNsModerateSuppression);
    295 }
    296 
    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));
    301 
    302   EXPECT_FALSE(ns_status);
    303   EXPECT_EQ(webrtc::kNsModerateSuppression, ns_mode);
    304 }
    305 
    306 TEST_F(AudioProcessingTest, CanSetRxNsMode) {
    307   EXPECT_EQ(0, voe_apm_->SetRxNsStatus(channel_, true));
    308 
    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);
    322 }
    323 
    324 TEST_F(AudioProcessingTest, VadIsDisabledByDefault) {
    325   bool vad_enabled;
    326   bool disabled_dtx;
    327   webrtc::VadModes vad_mode;
    328 
    329   EXPECT_EQ(0, voe_codec_->GetVADStatus(
    330       channel_, vad_enabled, vad_mode, disabled_dtx));
    331 
    332   EXPECT_FALSE(vad_enabled);
    333 }
    334 
    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.
    338   Sleep(500);
    339   EXPECT_EQ(1, voe_apm_->VoiceActivityIndicator(channel_));
    340 }
    341 
    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());
    347 }
    348 
    349 TEST_F(AudioProcessingTest, HighPassFilterIsOnByDefault) {
    350   EXPECT_TRUE(voe_apm_->IsHighPassFilterEnabled());
    351 }
    352 
    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());
    358 }
    359 
    360 TEST_F(AudioProcessingTest, StereoChannelSwappingIsOffByDefault) {
    361   EXPECT_FALSE(voe_apm_->IsStereoChannelSwappingEnabled());
    362 }
    363 
    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());
    369 }
    370 
    371 TEST_F(AudioProcessingTest, CanStartAndStopDebugRecording) {
    372   std::string output_path = webrtc::test::OutputPath();
    373   std::string output_file = output_path + "apm_debug.txt";
    374 
    375   EXPECT_EQ(0, voe_apm_->StartDebugRecording(output_file.c_str()));
    376   Sleep(1000);
    377   EXPECT_EQ(0, voe_apm_->StopDebugRecording());
    378 }
    379 
    380 #if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
    381 
    382 TEST_F(AudioProcessingTest, AgcIsOffByDefaultAndDigital) {
    383   bool agc_enabled = true;
    384   webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog;
    385 
    386   EXPECT_EQ(0, voe_apm_->GetAgcStatus(agc_enabled, agc_mode));
    387   EXPECT_FALSE(agc_enabled);
    388   EXPECT_EQ(webrtc::kAgcAdaptiveDigital, agc_mode);
    389 }
    390 
    391 TEST_F(AudioProcessingTest, CanEnableAgcInAdaptiveDigitalMode) {
    392   TryEnablingAgcWithMode(webrtc::kAgcAdaptiveDigital);
    393 }
    394 
    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));
    399 }
    400 
    401 TEST_F(AudioProcessingTest, EcIsDisabledAndAecmIsDefaultEcMode) {
    402   bool ec_enabled = true;
    403   webrtc::EcModes ec_mode = webrtc::kEcDefault;
    404 
    405   EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
    406   EXPECT_FALSE(ec_enabled);
    407   EXPECT_EQ(webrtc::kEcAecm, ec_mode);
    408 }
    409 
    410 TEST_F(AudioProcessingTest, TestVoiceActivityDetection) {
    411   TryDetectingSilence();
    412   TryDetectingSpeechAfterSilence();
    413 }
    414 
    415 #endif  // WEBRTC_IOS || WEBRTC_ANDROID
    416