LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/voice_engine - voe_audio_processing_impl.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 401 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 35 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/voice_engine/voe_audio_processing_impl.h"
      12             : 
      13             : #include "webrtc/base/logging.h"
      14             : #include "webrtc/modules/audio_processing/include/audio_processing.h"
      15             : #include "webrtc/system_wrappers/include/trace.h"
      16             : #include "webrtc/voice_engine/channel.h"
      17             : #include "webrtc/voice_engine/include/voe_errors.h"
      18             : #include "webrtc/voice_engine/transmit_mixer.h"
      19             : #include "webrtc/voice_engine/voice_engine_impl.h"
      20             : 
      21             : // TODO(andrew): move to a common place.
      22             : #define WEBRTC_VOICE_INIT_CHECK()                        \
      23             :   do {                                                   \
      24             :     if (!_shared->statistics().Initialized()) {          \
      25             :       _shared->SetLastError(VE_NOT_INITED, kTraceError); \
      26             :       return -1;                                         \
      27             :     }                                                    \
      28             :   } while (0)
      29             : 
      30             : #define WEBRTC_VOICE_INIT_CHECK_BOOL()                   \
      31             :   do {                                                   \
      32             :     if (!_shared->statistics().Initialized()) {          \
      33             :       _shared->SetLastError(VE_NOT_INITED, kTraceError); \
      34             :       return false;                                      \
      35             :     }                                                    \
      36             :   } while (0)
      37             : 
      38             : namespace webrtc {
      39             : 
      40             : #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
      41             : static const EcModes kDefaultEcMode = kEcAecm;
      42             : #else
      43             : static const EcModes kDefaultEcMode = kEcAec;
      44             : #endif
      45             : 
      46           0 : VoEAudioProcessing* VoEAudioProcessing::GetInterface(VoiceEngine* voiceEngine) {
      47           0 :   if (NULL == voiceEngine) {
      48           0 :     return NULL;
      49             :   }
      50           0 :   VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
      51           0 :   s->AddRef();
      52           0 :   return s;
      53             : }
      54             : 
      55           0 : VoEAudioProcessingImpl::VoEAudioProcessingImpl(voe::SharedData* shared)
      56           0 :     : _isAecMode(kDefaultEcMode == kEcAec), _shared(shared) {
      57             :   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
      58             :                "VoEAudioProcessingImpl::VoEAudioProcessingImpl() - ctor");
      59           0 : }
      60             : 
      61           0 : VoEAudioProcessingImpl::~VoEAudioProcessingImpl() {
      62             :   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
      63             :                "VoEAudioProcessingImpl::~VoEAudioProcessingImpl() - dtor");
      64           0 : }
      65             : 
      66           0 : int VoEAudioProcessingImpl::SetNsStatus(bool enable, NsModes mode) {
      67             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
      68             :                "SetNsStatus(enable=%d, mode=%d)", enable, mode);
      69           0 :   if (!_shared->statistics().Initialized()) {
      70           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
      71           0 :     return -1;
      72             :   }
      73             : 
      74           0 :   NoiseSuppression::Level nsLevel = kDefaultNsMode;
      75           0 :   switch (mode) {
      76             :     case kNsDefault:
      77           0 :       nsLevel = kDefaultNsMode;
      78           0 :       break;
      79             :     case kNsUnchanged:
      80           0 :       nsLevel = _shared->audio_processing()->noise_suppression()->level();
      81           0 :       break;
      82             :     case kNsConference:
      83           0 :       nsLevel = NoiseSuppression::kHigh;
      84           0 :       break;
      85             :     case kNsLowSuppression:
      86           0 :       nsLevel = NoiseSuppression::kLow;
      87           0 :       break;
      88             :     case kNsModerateSuppression:
      89           0 :       nsLevel = NoiseSuppression::kModerate;
      90           0 :       break;
      91             :     case kNsHighSuppression:
      92           0 :       nsLevel = NoiseSuppression::kHigh;
      93           0 :       break;
      94             :     case kNsVeryHighSuppression:
      95           0 :       nsLevel = NoiseSuppression::kVeryHigh;
      96           0 :       break;
      97             :   }
      98             : 
      99           0 :   if (_shared->audio_processing()->noise_suppression()->set_level(nsLevel) !=
     100             :       0) {
     101           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     102           0 :                           "SetNsStatus() failed to set Ns mode");
     103           0 :     return -1;
     104             :   }
     105           0 :   if (_shared->audio_processing()->noise_suppression()->Enable(enable) != 0) {
     106           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     107           0 :                           "SetNsStatus() failed to set Ns state");
     108           0 :     return -1;
     109             :   }
     110             : 
     111           0 :   return 0;
     112             : }
     113             : 
     114           0 : int VoEAudioProcessingImpl::GetNsStatus(bool& enabled, NsModes& mode) {
     115           0 :   if (!_shared->statistics().Initialized()) {
     116           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     117           0 :     return -1;
     118             :   }
     119             : 
     120           0 :   enabled = _shared->audio_processing()->noise_suppression()->is_enabled();
     121             :   NoiseSuppression::Level nsLevel =
     122           0 :       _shared->audio_processing()->noise_suppression()->level();
     123             : 
     124           0 :   switch (nsLevel) {
     125             :     case NoiseSuppression::kLow:
     126           0 :       mode = kNsLowSuppression;
     127           0 :       break;
     128             :     case NoiseSuppression::kModerate:
     129           0 :       mode = kNsModerateSuppression;
     130           0 :       break;
     131             :     case NoiseSuppression::kHigh:
     132           0 :       mode = kNsHighSuppression;
     133           0 :       break;
     134             :     case NoiseSuppression::kVeryHigh:
     135           0 :       mode = kNsVeryHighSuppression;
     136           0 :       break;
     137             :   }
     138           0 :   return 0;
     139             : }
     140             : 
     141           0 : int VoEAudioProcessingImpl::SetAgcStatus(bool enable, AgcModes mode) {
     142             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     143             :                "SetAgcStatus(enable=%d, mode=%d)", enable, mode);
     144           0 :   if (!_shared->statistics().Initialized()) {
     145           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     146           0 :     return -1;
     147             :   }
     148             : 
     149             : #if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID)
     150             :   if (mode == kAgcAdaptiveAnalog) {
     151             :     _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
     152             :                           "SetAgcStatus() invalid Agc mode for mobile device");
     153             :     return -1;
     154             :   }
     155             : #endif
     156             : 
     157           0 :   GainControl::Mode agcMode = kDefaultAgcMode;
     158           0 :   switch (mode) {
     159             :     case kAgcDefault:
     160           0 :       agcMode = kDefaultAgcMode;
     161           0 :       break;
     162             :     case kAgcUnchanged:
     163           0 :       agcMode = _shared->audio_processing()->gain_control()->mode();
     164           0 :       break;
     165             :     case kAgcFixedDigital:
     166           0 :       agcMode = GainControl::kFixedDigital;
     167           0 :       break;
     168             :     case kAgcAdaptiveAnalog:
     169           0 :       agcMode = GainControl::kAdaptiveAnalog;
     170           0 :       break;
     171             :     case kAgcAdaptiveDigital:
     172           0 :       agcMode = GainControl::kAdaptiveDigital;
     173           0 :       break;
     174             :   }
     175             : 
     176           0 :   if (_shared->audio_processing()->gain_control()->set_mode(agcMode) != 0) {
     177           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     178           0 :                           "SetAgcStatus() failed to set Agc mode");
     179           0 :     return -1;
     180             :   }
     181           0 :   if (_shared->audio_processing()->gain_control()->Enable(enable) != 0) {
     182           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     183           0 :                           "SetAgcStatus() failed to set Agc state");
     184           0 :     return -1;
     185             :   }
     186             : 
     187           0 :   if (agcMode != GainControl::kFixedDigital) {
     188             :     // Set Agc state in the ADM when adaptive Agc mode has been selected.
     189             :     // Note that we also enable the ADM Agc when Adaptive Digital mode is
     190             :     // used since we want to be able to provide the APM with updated mic
     191             :     // levels when the user modifies the mic level manually.
     192           0 :     if (_shared->audio_device()->SetAGC(enable) != 0) {
     193           0 :       _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning,
     194           0 :                             "SetAgcStatus() failed to set Agc mode");
     195             :     }
     196             :   }
     197             : 
     198           0 :   return 0;
     199             : }
     200             : 
     201           0 : int VoEAudioProcessingImpl::GetAgcStatus(bool& enabled, AgcModes& mode) {
     202           0 :   if (!_shared->statistics().Initialized()) {
     203           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     204           0 :     return -1;
     205             :   }
     206             : 
     207           0 :   enabled = _shared->audio_processing()->gain_control()->is_enabled();
     208             :   GainControl::Mode agcMode =
     209           0 :       _shared->audio_processing()->gain_control()->mode();
     210             : 
     211           0 :   switch (agcMode) {
     212             :     case GainControl::kFixedDigital:
     213           0 :       mode = kAgcFixedDigital;
     214           0 :       break;
     215             :     case GainControl::kAdaptiveAnalog:
     216           0 :       mode = kAgcAdaptiveAnalog;
     217           0 :       break;
     218             :     case GainControl::kAdaptiveDigital:
     219           0 :       mode = kAgcAdaptiveDigital;
     220           0 :       break;
     221             :   }
     222             : 
     223           0 :   return 0;
     224             : }
     225             : 
     226           0 : int VoEAudioProcessingImpl::SetAgcConfig(AgcConfig config) {
     227             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     228             :                "SetAgcConfig()");
     229           0 :   if (!_shared->statistics().Initialized()) {
     230           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     231           0 :     return -1;
     232             :   }
     233             : 
     234           0 :   if (_shared->audio_processing()->gain_control()->set_target_level_dbfs(
     235           0 :           config.targetLeveldBOv) != 0) {
     236           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     237             :                           "SetAgcConfig() failed to set target peak |level|"
     238           0 :                           " (or envelope) of the Agc");
     239           0 :     return -1;
     240             :   }
     241           0 :   if (_shared->audio_processing()->gain_control()->set_compression_gain_db(
     242           0 :           config.digitalCompressionGaindB) != 0) {
     243           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     244             :                           "SetAgcConfig() failed to set the range in |gain| "
     245           0 :                           "the digital compression stage may apply");
     246           0 :     return -1;
     247             :   }
     248           0 :   if (_shared->audio_processing()->gain_control()->enable_limiter(
     249           0 :           config.limiterEnable) != 0) {
     250           0 :     _shared->SetLastError(
     251             :         VE_APM_ERROR, kTraceError,
     252           0 :         "SetAgcConfig() failed to set hard limiter to the signal");
     253           0 :     return -1;
     254             :   }
     255             : 
     256           0 :   return 0;
     257             : }
     258             : 
     259           0 : int VoEAudioProcessingImpl::GetAgcConfig(AgcConfig& config) {
     260           0 :   if (!_shared->statistics().Initialized()) {
     261           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     262           0 :     return -1;
     263             :   }
     264             : 
     265           0 :   config.targetLeveldBOv =
     266           0 :       _shared->audio_processing()->gain_control()->target_level_dbfs();
     267           0 :   config.digitalCompressionGaindB =
     268           0 :       _shared->audio_processing()->gain_control()->compression_gain_db();
     269           0 :   config.limiterEnable =
     270           0 :       _shared->audio_processing()->gain_control()->is_limiter_enabled();
     271             : 
     272           0 :   return 0;
     273             : }
     274             : 
     275           0 : bool VoEAudioProcessing::DriftCompensationSupported() {
     276             : #if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
     277             :   return true;
     278             : #else
     279           0 :   return false;
     280             : #endif
     281             : }
     282             : 
     283           0 : int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
     284           0 :   WEBRTC_VOICE_INIT_CHECK();
     285             : 
     286           0 :   if (!DriftCompensationSupported()) {
     287           0 :     _shared->SetLastError(
     288             :         VE_APM_ERROR, kTraceWarning,
     289           0 :         "Drift compensation is not supported on this platform.");
     290           0 :     return -1;
     291             :   }
     292             : 
     293           0 :   EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
     294           0 :   if (aec->enable_drift_compensation(enable) != 0) {
     295           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     296           0 :                           "aec->enable_drift_compensation() failed");
     297           0 :     return -1;
     298             :   }
     299           0 :   return 0;
     300             : }
     301             : 
     302           0 : bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
     303           0 :   WEBRTC_VOICE_INIT_CHECK_BOOL();
     304             : 
     305           0 :   EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
     306           0 :   return aec->is_drift_compensation_enabled();
     307             : }
     308             : 
     309           0 : int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
     310             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     311             :                "SetEcStatus(enable=%d, mode=%d)", enable, mode);
     312           0 :   if (!_shared->statistics().Initialized()) {
     313           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     314           0 :     return -1;
     315             :   }
     316             : 
     317             :   // AEC mode
     318           0 :   if ((mode == kEcDefault) || (mode == kEcConference) || (mode == kEcAec) ||
     319           0 :       ((mode == kEcUnchanged) && (_isAecMode == true))) {
     320           0 :     if (enable) {
     321             :       // Disable the AECM before enable the AEC
     322           0 :       if (_shared->audio_processing()->echo_control_mobile()->is_enabled()) {
     323           0 :         _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
     324           0 :                               "SetEcStatus() disable AECM before enabling AEC");
     325           0 :         if (_shared->audio_processing()->echo_control_mobile()->Enable(false) !=
     326             :             0) {
     327           0 :           _shared->SetLastError(VE_APM_ERROR, kTraceError,
     328           0 :                                 "SetEcStatus() failed to disable AECM");
     329           0 :           return -1;
     330             :         }
     331             :       }
     332             :     }
     333           0 :     if (_shared->audio_processing()->echo_cancellation()->Enable(enable) != 0) {
     334           0 :       _shared->SetLastError(VE_APM_ERROR, kTraceError,
     335           0 :                             "SetEcStatus() failed to set AEC state");
     336           0 :       return -1;
     337             :     }
     338           0 :     if (mode == kEcConference) {
     339           0 :       if (_shared->audio_processing()
     340           0 :               ->echo_cancellation()
     341           0 :               ->set_suppression_level(EchoCancellation::kHighSuppression) !=
     342             :           0) {
     343           0 :         _shared->SetLastError(
     344             :             VE_APM_ERROR, kTraceError,
     345           0 :             "SetEcStatus() failed to set aggressiveness to high");
     346           0 :         return -1;
     347             :       }
     348             :     } else {
     349           0 :       if (_shared->audio_processing()
     350           0 :               ->echo_cancellation()
     351           0 :               ->set_suppression_level(EchoCancellation::kModerateSuppression) !=
     352             :           0) {
     353           0 :         _shared->SetLastError(
     354             :             VE_APM_ERROR, kTraceError,
     355           0 :             "SetEcStatus() failed to set aggressiveness to moderate");
     356           0 :         return -1;
     357             :       }
     358             :     }
     359             : 
     360           0 :     _isAecMode = true;
     361           0 :   } else if ((mode == kEcAecm) ||
     362           0 :              ((mode == kEcUnchanged) && (_isAecMode == false))) {
     363           0 :     if (enable) {
     364             :       // Disable the AEC before enable the AECM
     365           0 :       if (_shared->audio_processing()->echo_cancellation()->is_enabled()) {
     366           0 :         _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
     367           0 :                               "SetEcStatus() disable AEC before enabling AECM");
     368           0 :         if (_shared->audio_processing()->echo_cancellation()->Enable(false) !=
     369             :             0) {
     370           0 :           _shared->SetLastError(VE_APM_ERROR, kTraceError,
     371           0 :                                 "SetEcStatus() failed to disable AEC");
     372           0 :           return -1;
     373             :         }
     374             :       }
     375             :     }
     376           0 :     if (_shared->audio_processing()->echo_control_mobile()->Enable(enable) !=
     377             :         0) {
     378           0 :       _shared->SetLastError(VE_APM_ERROR, kTraceError,
     379           0 :                             "SetEcStatus() failed to set AECM state");
     380           0 :       return -1;
     381             :     }
     382           0 :     _isAecMode = false;
     383             :   } else {
     384           0 :     _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
     385           0 :                           "SetEcStatus() invalid EC mode");
     386           0 :     return -1;
     387             :   }
     388             : 
     389           0 :   return 0;
     390             : }
     391             : 
     392           0 : int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode) {
     393           0 :   if (!_shared->statistics().Initialized()) {
     394           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     395           0 :     return -1;
     396             :   }
     397             : 
     398           0 :   if (_isAecMode == true) {
     399           0 :     mode = kEcAec;
     400           0 :     enabled = _shared->audio_processing()->echo_cancellation()->is_enabled();
     401             :   } else {
     402           0 :     mode = kEcAecm;
     403           0 :     enabled = _shared->audio_processing()->echo_control_mobile()->is_enabled();
     404             :   }
     405             : 
     406           0 :   return 0;
     407             : }
     408             : 
     409           0 : void VoEAudioProcessingImpl::SetDelayOffsetMs(int offset) {
     410             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     411             :                "SetDelayOffsetMs(offset = %d)", offset);
     412           0 :   _shared->audio_processing()->set_delay_offset_ms(offset);
     413           0 : }
     414             : 
     415           0 : int VoEAudioProcessingImpl::DelayOffsetMs() {
     416           0 :   return _shared->audio_processing()->delay_offset_ms();
     417             : }
     418             : 
     419           0 : int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG) {
     420             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     421             :                "SetAECMMode(mode = %d)", mode);
     422           0 :   if (!_shared->statistics().Initialized()) {
     423           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     424           0 :     return -1;
     425             :   }
     426             : 
     427             :   EchoControlMobile::RoutingMode aecmMode(
     428           0 :       EchoControlMobile::kQuietEarpieceOrHeadset);
     429             : 
     430           0 :   switch (mode) {
     431             :     case kAecmQuietEarpieceOrHeadset:
     432           0 :       aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
     433           0 :       break;
     434             :     case kAecmEarpiece:
     435           0 :       aecmMode = EchoControlMobile::kEarpiece;
     436           0 :       break;
     437             :     case kAecmLoudEarpiece:
     438           0 :       aecmMode = EchoControlMobile::kLoudEarpiece;
     439           0 :       break;
     440             :     case kAecmSpeakerphone:
     441           0 :       aecmMode = EchoControlMobile::kSpeakerphone;
     442           0 :       break;
     443             :     case kAecmLoudSpeakerphone:
     444           0 :       aecmMode = EchoControlMobile::kLoudSpeakerphone;
     445           0 :       break;
     446             :   }
     447             : 
     448           0 :   if (_shared->audio_processing()->echo_control_mobile()->set_routing_mode(
     449           0 :           aecmMode) != 0) {
     450           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     451           0 :                           "SetAECMMode() failed to set AECM routing mode");
     452           0 :     return -1;
     453             :   }
     454           0 :   if (_shared->audio_processing()->echo_control_mobile()->enable_comfort_noise(
     455           0 :           enableCNG) != 0) {
     456           0 :     _shared->SetLastError(
     457             :         VE_APM_ERROR, kTraceError,
     458           0 :         "SetAECMMode() failed to set comfort noise state for AECM");
     459           0 :     return -1;
     460             :   }
     461             : 
     462           0 :   return 0;
     463             : }
     464             : 
     465           0 : int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG) {
     466           0 :   if (!_shared->statistics().Initialized()) {
     467           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     468           0 :     return -1;
     469             :   }
     470             : 
     471           0 :   enabledCNG = false;
     472             : 
     473             :   EchoControlMobile::RoutingMode aecmMode =
     474           0 :       _shared->audio_processing()->echo_control_mobile()->routing_mode();
     475           0 :   enabledCNG = _shared->audio_processing()
     476           0 :                    ->echo_control_mobile()
     477           0 :                    ->is_comfort_noise_enabled();
     478             : 
     479           0 :   switch (aecmMode) {
     480             :     case EchoControlMobile::kQuietEarpieceOrHeadset:
     481           0 :       mode = kAecmQuietEarpieceOrHeadset;
     482           0 :       break;
     483             :     case EchoControlMobile::kEarpiece:
     484           0 :       mode = kAecmEarpiece;
     485           0 :       break;
     486             :     case EchoControlMobile::kLoudEarpiece:
     487           0 :       mode = kAecmLoudEarpiece;
     488           0 :       break;
     489             :     case EchoControlMobile::kSpeakerphone:
     490           0 :       mode = kAecmSpeakerphone;
     491           0 :       break;
     492             :     case EchoControlMobile::kLoudSpeakerphone:
     493           0 :       mode = kAecmLoudSpeakerphone;
     494           0 :       break;
     495             :   }
     496             : 
     497           0 :   return 0;
     498             : }
     499             : 
     500           0 : int VoEAudioProcessingImpl::EnableHighPassFilter(bool enable) {
     501             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     502             :                "EnableHighPassFilter(%d)", enable);
     503           0 :   if (_shared->audio_processing()->high_pass_filter()->Enable(enable) !=
     504             :       AudioProcessing::kNoError) {
     505           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     506           0 :                           "HighPassFilter::Enable() failed.");
     507           0 :     return -1;
     508             :   }
     509             : 
     510           0 :   return 0;
     511             : }
     512             : 
     513           0 : bool VoEAudioProcessingImpl::IsHighPassFilterEnabled() {
     514           0 :   return _shared->audio_processing()->high_pass_filter()->is_enabled();
     515             : }
     516             : 
     517           0 : int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel) {
     518             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     519             :                "VoiceActivityIndicator(channel=%d)", channel);
     520           0 :   if (!_shared->statistics().Initialized()) {
     521           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     522           0 :     return -1;
     523             :   }
     524             : 
     525           0 :   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
     526           0 :   voe::Channel* channelPtr = ch.channel();
     527           0 :   if (channelPtr == NULL) {
     528           0 :     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
     529           0 :                           "VoiceActivityIndicator() failed to locate channel");
     530           0 :     return -1;
     531             :   }
     532           0 :   int activity(-1);
     533           0 :   channelPtr->VoiceActivityIndicator(activity);
     534             : 
     535           0 :   return activity;
     536             : }
     537             : 
     538           0 : int VoEAudioProcessingImpl::SetEcMetricsStatus(bool enable) {
     539             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     540             :                "SetEcMetricsStatus(enable=%d)", enable);
     541           0 :   if (!_shared->statistics().Initialized()) {
     542           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     543           0 :     return -1;
     544             :   }
     545             : 
     546           0 :   if ((_shared->audio_processing()->echo_cancellation()->enable_metrics(
     547           0 :            enable) != 0) ||
     548           0 :       (_shared->audio_processing()->echo_cancellation()->enable_delay_logging(
     549           0 :            enable) != 0)) {
     550           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceError,
     551           0 :                           "SetEcMetricsStatus() unable to set EC metrics mode");
     552           0 :     return -1;
     553             :   }
     554           0 :   return 0;
     555             : }
     556             : 
     557           0 : int VoEAudioProcessingImpl::GetEcMetricsStatus(bool& enabled) {
     558           0 :   if (!_shared->statistics().Initialized()) {
     559           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     560           0 :     return -1;
     561             :   }
     562             : 
     563             :   bool echo_mode =
     564           0 :       _shared->audio_processing()->echo_cancellation()->are_metrics_enabled();
     565           0 :   bool delay_mode = _shared->audio_processing()
     566           0 :                         ->echo_cancellation()
     567           0 :                         ->is_delay_logging_enabled();
     568             : 
     569           0 :   if (echo_mode != delay_mode) {
     570           0 :     _shared->SetLastError(
     571             :         VE_APM_ERROR, kTraceError,
     572           0 :         "GetEcMetricsStatus() delay logging and echo mode are not the same");
     573           0 :     return -1;
     574             :   }
     575             : 
     576           0 :   enabled = echo_mode;
     577             : 
     578           0 :   return 0;
     579             : }
     580             : 
     581           0 : int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
     582             :                                            int& ERLE,
     583             :                                            int& RERL,
     584             :                                            int& A_NLP) {
     585           0 :   if (!_shared->statistics().Initialized()) {
     586           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     587           0 :     return -1;
     588             :   }
     589           0 :   if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
     590           0 :     _shared->SetLastError(
     591             :         VE_APM_ERROR, kTraceWarning,
     592           0 :         "GetEchoMetrics() AudioProcessingModule AEC is not enabled");
     593           0 :     return -1;
     594             :   }
     595             : 
     596             :   // Get Echo Metrics from Audio Processing Module.
     597           0 :   EchoCancellation::Metrics echoMetrics;
     598           0 :   if (_shared->audio_processing()->echo_cancellation()->GetMetrics(
     599           0 :           &echoMetrics)) {
     600             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
     601             :                  "GetEchoMetrics(), AudioProcessingModule metrics error");
     602           0 :     return -1;
     603             :   }
     604             : 
     605             :   // Echo quality metrics.
     606           0 :   ERL = echoMetrics.echo_return_loss.instant;
     607           0 :   ERLE = echoMetrics.echo_return_loss_enhancement.instant;
     608           0 :   RERL = echoMetrics.residual_echo_return_loss.instant;
     609           0 :   A_NLP = echoMetrics.a_nlp.instant;
     610             : 
     611           0 :   return 0;
     612             : }
     613             : 
     614           0 : int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median,
     615             :                                               int& delay_std,
     616             :                                               float& fraction_poor_delays) {
     617           0 :   if (!_shared->statistics().Initialized()) {
     618           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     619           0 :     return -1;
     620             :   }
     621           0 :   if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
     622           0 :     _shared->SetLastError(
     623             :         VE_APM_ERROR, kTraceWarning,
     624           0 :         "GetEcDelayMetrics() AudioProcessingModule AEC is not enabled");
     625           0 :     return -1;
     626             :   }
     627             : 
     628           0 :   int median = 0;
     629           0 :   int std = 0;
     630           0 :   float poor_fraction = 0;
     631             :   // Get delay-logging values from Audio Processing Module.
     632           0 :   if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics(
     633           0 :           &median, &std, &poor_fraction)) {
     634             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
     635             :                  "GetEcDelayMetrics(), AudioProcessingModule delay-logging "
     636             :                  "error");
     637           0 :     return -1;
     638             :   }
     639             : 
     640             :   // EC delay-logging metrics
     641           0 :   delay_median = median;
     642           0 :   delay_std = std;
     643           0 :   fraction_poor_delays = poor_fraction;
     644             : 
     645           0 :   return 0;
     646             : }
     647             : 
     648           0 : int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) {
     649             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     650             :                "StartDebugRecording()");
     651           0 :   if (!_shared->statistics().Initialized()) {
     652           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     653           0 :     return -1;
     654             :   }
     655             : 
     656           0 :   return _shared->audio_processing()->StartDebugRecording(fileNameUTF8, -1);
     657             : }
     658             : 
     659           0 : int VoEAudioProcessingImpl::StartDebugRecording(FILE* file_handle) {
     660             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     661             :                "StartDebugRecording()");
     662           0 :   if (!_shared->statistics().Initialized()) {
     663           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     664           0 :     return -1;
     665             :   }
     666             : 
     667           0 :   return _shared->audio_processing()->StartDebugRecording(file_handle, -1);
     668             : }
     669             : 
     670           0 : int VoEAudioProcessingImpl::StopDebugRecording() {
     671             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     672             :                "StopDebugRecording()");
     673           0 :   if (!_shared->statistics().Initialized()) {
     674           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     675           0 :     return -1;
     676             :   }
     677             : 
     678           0 :   return _shared->audio_processing()->StopDebugRecording();
     679             : }
     680             : 
     681           0 : int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable) {
     682             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     683             :                "SetTypingDetectionStatus()");
     684             : #if !WEBRTC_VOICE_ENGINE_TYPING_DETECTION
     685             :   NOT_SUPPORTED(_shared->statistics());
     686             : #else
     687           0 :   if (!_shared->statistics().Initialized()) {
     688           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     689           0 :     return -1;
     690             :   }
     691             : 
     692             :   // Just use the VAD state to determine if we should enable typing detection
     693             :   // or not
     694             : 
     695           0 :   if (_shared->audio_processing()->voice_detection()->Enable(enable)) {
     696           0 :     _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
     697           0 :                           "SetTypingDetectionStatus() failed to set VAD state");
     698           0 :     return -1;
     699             :   }
     700           0 :   if (_shared->audio_processing()->voice_detection()->set_likelihood(
     701           0 :           VoiceDetection::kVeryLowLikelihood)) {
     702           0 :     _shared->SetLastError(
     703             :         VE_APM_ERROR, kTraceWarning,
     704           0 :         "SetTypingDetectionStatus() failed to set VAD likelihood to low");
     705           0 :     return -1;
     706             :   }
     707             : 
     708           0 :   return 0;
     709             : #endif
     710             : }
     711             : 
     712           0 : int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled) {
     713           0 :   if (!_shared->statistics().Initialized()) {
     714           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     715           0 :     return -1;
     716             :   }
     717             :   // Just use the VAD state to determine if we should enable typing
     718             :   // detection or not
     719             : 
     720           0 :   enabled = _shared->audio_processing()->voice_detection()->is_enabled();
     721             : 
     722           0 :   return 0;
     723             : }
     724             : 
     725           0 : int VoEAudioProcessingImpl::TimeSinceLastTyping(int& seconds) {
     726             : #if !WEBRTC_VOICE_ENGINE_TYPING_DETECTION
     727             :   NOT_SUPPORTED(_shared->statistics());
     728             : #else
     729           0 :   if (!_shared->statistics().Initialized()) {
     730           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     731           0 :     return -1;
     732             :   }
     733             :   // Check if typing detection is enabled
     734           0 :   bool enabled = _shared->audio_processing()->voice_detection()->is_enabled();
     735           0 :   if (enabled) {
     736           0 :     _shared->transmit_mixer()->TimeSinceLastTyping(seconds);
     737           0 :     return 0;
     738             :   } else {
     739           0 :     _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
     740           0 :                           "SetTypingDetectionStatus is not enabled");
     741           0 :     return -1;
     742             :   }
     743             : #endif
     744             : }
     745             : 
     746           0 : int VoEAudioProcessingImpl::SetTypingDetectionParameters(int timeWindow,
     747             :                                                          int costPerTyping,
     748             :                                                          int reportingThreshold,
     749             :                                                          int penaltyDecay,
     750             :                                                          int typeEventDelay) {
     751             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     752             :                "SetTypingDetectionParameters()");
     753             : #if !WEBRTC_VOICE_ENGINE_TYPING_DETECTION
     754             :   NOT_SUPPORTED(_shared->statistics());
     755             : #else
     756           0 :   if (!_shared->statistics().Initialized()) {
     757           0 :     _shared->statistics().SetLastError(VE_NOT_INITED, kTraceError);
     758           0 :     return -1;
     759             :   }
     760           0 :   return (_shared->transmit_mixer()->SetTypingDetectionParameters(
     761             :       timeWindow, costPerTyping, reportingThreshold, penaltyDecay,
     762           0 :       typeEventDelay));
     763             : #endif
     764             : }
     765             : 
     766           0 : void VoEAudioProcessingImpl::EnableStereoChannelSwapping(bool enable) {
     767           0 :   _shared->transmit_mixer()->EnableStereoChannelSwapping(enable);
     768           0 : }
     769             : 
     770           0 : bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
     771           0 :   return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
     772             : }
     773             : 
     774             : }  // namespace webrtc

Generated by: LCOV version 1.13