1246 lines
38 KiB
C++
1246 lines
38 KiB
C++
/*
|
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "voe_audio_processing_impl.h"
|
|
|
|
#include "audio_processing.h"
|
|
#include "channel.h"
|
|
#include "critical_section_wrapper.h"
|
|
#include "trace.h"
|
|
#include "voe_errors.h"
|
|
#include "voice_engine_impl.h"
|
|
|
|
namespace webrtc {
|
|
|
|
VoEAudioProcessing* VoEAudioProcessing::GetInterface(
|
|
VoiceEngine* voiceEngine)
|
|
{
|
|
#ifndef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
|
|
return NULL;
|
|
#else
|
|
if (NULL == voiceEngine)
|
|
{
|
|
return NULL;
|
|
}
|
|
VoiceEngineImpl* s = reinterpret_cast<VoiceEngineImpl*> (voiceEngine);
|
|
VoEAudioProcessingImpl* d = s;
|
|
(*d)++;
|
|
return (d);
|
|
#endif
|
|
}
|
|
|
|
#ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
|
|
VoEAudioProcessingImpl::VoEAudioProcessingImpl():
|
|
_isAecMode(WEBRTC_VOICE_ENGINE_EC_DEFAULT_MODE == EcAec?
|
|
true : false)
|
|
{
|
|
WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,-1),
|
|
"VoEAudioProcessingImpl::VoEAudioProcessingImpl() - ctor");
|
|
}
|
|
|
|
VoEAudioProcessingImpl::~VoEAudioProcessingImpl()
|
|
{
|
|
WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,-1),
|
|
"VoEAudioProcessingImpl::~VoEAudioProcessingImpl() - dtor");
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::Release()
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"VoEAudioProcessing::Release()");
|
|
(*this)--;
|
|
int refCount = GetCount();
|
|
if (refCount < 0)
|
|
{
|
|
Reset(); // reset reference counter to zero => OK to delete VE
|
|
_engineStatistics.SetLastError(
|
|
VE_INTERFACE_NOT_FOUND, kTraceWarning);
|
|
return (-1);
|
|
}
|
|
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
|
|
"VoEAudioProcessing reference counter = %d", refCount);
|
|
return (refCount);
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetNsStatus(bool enable, NsModes mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetNsStatus(enable=%d, mode=%d)", enable, mode);
|
|
#ifdef WEBRTC_VOICE_ENGINE_NR
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
NoiseSuppression::Level nsLevel(
|
|
(NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE);
|
|
switch (mode)
|
|
{
|
|
case kNsDefault:
|
|
nsLevel = (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE;
|
|
break;
|
|
case kNsUnchanged:
|
|
nsLevel = _audioProcessingModulePtr->noise_suppression()->level();
|
|
break;
|
|
case kNsConference:
|
|
nsLevel = NoiseSuppression::kHigh;
|
|
break;
|
|
case kNsLowSuppression:
|
|
nsLevel = NoiseSuppression::kLow;
|
|
break;
|
|
case kNsModerateSuppression:
|
|
nsLevel = NoiseSuppression::kModerate;
|
|
break;
|
|
case kNsHighSuppression:
|
|
nsLevel = NoiseSuppression::kHigh;
|
|
break;
|
|
case kNsVeryHighSuppression:
|
|
nsLevel = NoiseSuppression::kVeryHigh;
|
|
break;
|
|
default:
|
|
_engineStatistics.SetLastError(
|
|
VE_INVALID_ARGUMENT, kTraceError,
|
|
"SetNsStatus() invalid Ns mode");
|
|
return -1;
|
|
}
|
|
|
|
if (_audioProcessingModulePtr->noise_suppression()->set_level(nsLevel) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(VE_APM_ERROR, kTraceError,
|
|
"SetNsStatus() failed to set Ns mode");
|
|
return -1;
|
|
}
|
|
if (_audioProcessingModulePtr->noise_suppression()->Enable(enable) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetNsStatus() failed to set Ns state");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetNsStatus() Ns is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetNsStatus(bool& enabled, NsModes& mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetNsStatus(enabled=?, mode=?)");
|
|
#ifdef WEBRTC_VOICE_ENGINE_NR
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
bool enable(false);
|
|
NoiseSuppression::Level nsLevel(
|
|
(NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE);
|
|
|
|
enable = _audioProcessingModulePtr->noise_suppression()->is_enabled();
|
|
nsLevel = _audioProcessingModulePtr->noise_suppression()->level();
|
|
|
|
enabled = enable;
|
|
|
|
switch (nsLevel)
|
|
{
|
|
case NoiseSuppression::kLow:
|
|
mode = kNsLowSuppression;
|
|
break;
|
|
case NoiseSuppression::kModerate:
|
|
mode = kNsModerateSuppression;
|
|
break;
|
|
case NoiseSuppression::kHigh:
|
|
mode = kNsHighSuppression;
|
|
break;
|
|
case NoiseSuppression::kVeryHigh:
|
|
mode = kNsVeryHighSuppression;
|
|
break;
|
|
default:
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"GetNsStatus() invalid Ns mode");
|
|
return -1;
|
|
}
|
|
|
|
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetNsStatus() => enabled=% d, mode=%d",enabled, mode);
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"GetNsStatus() Ns is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetAgcStatus(bool enable, AgcModes mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetAgcStatus(enable=%d, mode=%d)", enable, mode);
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
#if defined(MAC_IPHONE) || defined(ATA) || defined(ANDROID)
|
|
if (mode == kAgcAdaptiveAnalog)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_INVALID_ARGUMENT, kTraceError,
|
|
"SetAgcStatus() invalid Agc mode for mobile device");
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
GainControl::Mode agcMode(
|
|
(GainControl::Mode)WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE);
|
|
switch (mode)
|
|
{
|
|
case kAgcDefault:
|
|
agcMode = (GainControl::Mode)WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE;
|
|
break;
|
|
case kAgcUnchanged:
|
|
agcMode = _audioProcessingModulePtr->gain_control()->mode();;
|
|
break;
|
|
case kAgcFixedDigital:
|
|
agcMode = GainControl::kFixedDigital;
|
|
break;
|
|
case kAgcAdaptiveAnalog:
|
|
agcMode = GainControl::kAdaptiveAnalog;
|
|
break;
|
|
case kAgcAdaptiveDigital:
|
|
agcMode = GainControl::kAdaptiveDigital;
|
|
break;
|
|
default:
|
|
_engineStatistics.SetLastError(VE_INVALID_ARGUMENT, kTraceError,
|
|
"SetAgcStatus() invalid Agc mode");
|
|
return -1;
|
|
}
|
|
|
|
if (_audioProcessingModulePtr->gain_control()->set_mode(agcMode) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetAgcStatus() failed to set Agc mode");
|
|
return -1;
|
|
}
|
|
if (_audioProcessingModulePtr->gain_control()->Enable(enable) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetAgcStatus() failed to set Agc state");
|
|
return -1;
|
|
}
|
|
|
|
if (agcMode != GainControl::kFixedDigital)
|
|
{
|
|
// Set Agc state in the ADM when adaptive Agc mode has been selected.
|
|
// Note that we also enable the ADM Agc when Adaptive Digital mode is
|
|
// used since we want to be able to provide the APM with updated mic
|
|
// levels when the user modifies the mic level manually.
|
|
if (_audioDevicePtr->SetAGC(enable) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning,
|
|
"SetAgcStatus() failed to set Agc mode");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetAgcStatus() Agc is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetAgcStatus(bool& enabled, AgcModes& mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetAgcStatus(enabled=?, mode=?)");
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
bool enable(false);
|
|
GainControl::Mode agcMode(
|
|
(GainControl::Mode)WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE);
|
|
|
|
enable = _audioProcessingModulePtr->gain_control()->is_enabled();
|
|
agcMode = _audioProcessingModulePtr->gain_control()->mode();
|
|
|
|
enabled = enable;
|
|
|
|
switch (agcMode)
|
|
{
|
|
case GainControl::kFixedDigital:
|
|
mode = kAgcFixedDigital;
|
|
break;
|
|
case GainControl::kAdaptiveAnalog:
|
|
mode = kAgcAdaptiveAnalog;
|
|
break;
|
|
case GainControl::kAdaptiveDigital:
|
|
mode = kAgcAdaptiveDigital;
|
|
break;
|
|
default:
|
|
_engineStatistics.SetLastError(VE_APM_ERROR, kTraceError,
|
|
"GetAgcStatus() invalid Agc mode");
|
|
return -1;
|
|
}
|
|
|
|
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetAgcStatus() => enabled=%d, mode=%d", enabled, mode);
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"GetAgcStatus() Agc is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetAgcConfig(const AgcConfig config)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetAgcConfig()");
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
if (_audioProcessingModulePtr->gain_control()->set_target_level_dbfs(
|
|
config.targetLeveldBOv) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetAgcConfig() failed to set target peak |level|"
|
|
" (or envelope) of the Agc");
|
|
return -1;
|
|
}
|
|
if (_audioProcessingModulePtr->gain_control()->set_compression_gain_db(
|
|
config.digitalCompressionGaindB) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetAgcConfig() failed to set the range in |gain|"
|
|
"the digital compression stage may apply");
|
|
return -1;
|
|
}
|
|
if (_audioProcessingModulePtr->gain_control()->enable_limiter(
|
|
config.limiterEnable) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetAgcConfig() failed to set hard limiter to the signal");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetAgcConfig() EC is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetAgcConfig(AgcConfig &config)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetAgcConfig(config=?)");
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
config.targetLeveldBOv =
|
|
_audioProcessingModulePtr->gain_control()->target_level_dbfs();
|
|
config.digitalCompressionGaindB =
|
|
_audioProcessingModulePtr->gain_control()->compression_gain_db();
|
|
config.limiterEnable =
|
|
_audioProcessingModulePtr->gain_control()->is_limiter_enabled();
|
|
|
|
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetAgcConfig() => targetLeveldBOv=%u, "
|
|
"digitalCompressionGaindB=%u, limiterEnable=%d",
|
|
config.targetLeveldBOv,
|
|
config.digitalCompressionGaindB,
|
|
config.limiterEnable);
|
|
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"GetAgcConfig() EC is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetRxNsStatus(int channel,
|
|
bool enable,
|
|
NsModes mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetRxNsStatus(channel=%d, enable=%d, mode=%d)",
|
|
channel, (int)enable, (int)mode);
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
voe::ScopedChannel sc(_channelManager, channel);
|
|
voe::Channel* channelPtr = sc.ChannelPtr();
|
|
if (channelPtr == NULL)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_CHANNEL_NOT_VALID, kTraceError,
|
|
"SetRxNsStatus() failed to locate channel");
|
|
return -1;
|
|
}
|
|
return channelPtr->SetRxNsStatus(enable, mode);
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetRxNsStatus() AGC is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetRxNsStatus(int channel,
|
|
bool& enabled,
|
|
NsModes& mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetRxNsStatus(channel=%d, enable=?, mode=?)", channel);
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
voe::ScopedChannel sc(_channelManager, channel);
|
|
voe::Channel* channelPtr = sc.ChannelPtr();
|
|
if (channelPtr == NULL)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_CHANNEL_NOT_VALID, kTraceError,
|
|
"GetRxNsStatus() failed to locate channel");
|
|
return -1;
|
|
}
|
|
return channelPtr->GetRxNsStatus(enabled, mode);
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"GetRxNsStatus() Agc is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetRxAgcStatus(int channel,
|
|
bool enable,
|
|
AgcModes mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetRxAgcStatus(channel=%d, enable=%d, mode=%d)",
|
|
channel, (int)enable, (int)mode);
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
voe::ScopedChannel sc(_channelManager, channel);
|
|
voe::Channel* channelPtr = sc.ChannelPtr();
|
|
if (channelPtr == NULL)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_CHANNEL_NOT_VALID, kTraceError,
|
|
"SetRxAgcStatus() failed to locate channel");
|
|
return -1;
|
|
}
|
|
return channelPtr->SetRxAgcStatus(enable, mode);
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetRxAgcStatus() Agc is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetRxAgcStatus(int channel,
|
|
bool& enabled,
|
|
AgcModes& mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetRxAgcStatus(channel=%d, enable=?, mode=?)", channel);
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
voe::ScopedChannel sc(_channelManager, channel);
|
|
voe::Channel* channelPtr = sc.ChannelPtr();
|
|
if (channelPtr == NULL)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_CHANNEL_NOT_VALID, kTraceError,
|
|
"GetRxAgcStatus() failed to locate channel");
|
|
return -1;
|
|
}
|
|
return channelPtr->GetRxAgcStatus(enabled, mode);
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"GetRxAgcStatus() Agc is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetRxAgcConfig(int channel, const AgcConfig config)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetRxAgcConfig(channel=%d)", channel);
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
voe::ScopedChannel sc(_channelManager, channel);
|
|
voe::Channel* channelPtr = sc.ChannelPtr();
|
|
if (channelPtr == NULL)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_CHANNEL_NOT_VALID, kTraceError,
|
|
"SetRxAgcConfig() failed to locate channel");
|
|
return -1;
|
|
}
|
|
return channelPtr->SetRxAgcConfig(config);
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetRxAgcConfig() Agc is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetRxAgcConfig(int channel, AgcConfig& config)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetRxAgcConfig(channel=%d)", channel);
|
|
#ifdef WEBRTC_VOICE_ENGINE_AGC
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
voe::ScopedChannel sc(_channelManager, channel);
|
|
voe::Channel* channelPtr = sc.ChannelPtr();
|
|
if (channelPtr == NULL)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_CHANNEL_NOT_VALID, kTraceError,
|
|
"GetRxAgcConfig() failed to locate channel");
|
|
return -1;
|
|
}
|
|
return channelPtr->GetRxAgcConfig(config);
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"GetRxAgcConfig() Agc is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetEcStatus(enable=%d, mode=%d)", enable, mode);
|
|
#ifdef WEBRTC_VOICE_ENGINE_ECHO
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
// AEC mode
|
|
if ((mode == kEcDefault) ||
|
|
(mode == kEcConference) ||
|
|
(mode == kEcAec) ||
|
|
((mode == kEcUnchanged) &&
|
|
(_isAecMode == true)))
|
|
{
|
|
if (enable)
|
|
{
|
|
// Disable the AECM before enable the AEC
|
|
if (_audioProcessingModulePtr->echo_control_mobile()->is_enabled())
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceWarning,
|
|
"SetEcStatus() disable AECM before enabling AEC");
|
|
if (_audioProcessingModulePtr->echo_control_mobile()->
|
|
Enable(false) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetEcStatus() failed to disable AECM");
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
if (_audioProcessingModulePtr->echo_cancellation()->Enable(enable) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetEcStatus() failed to set AEC state");
|
|
return -1;
|
|
}
|
|
#ifdef CLOCK_SKEW_COMP
|
|
if (_audioProcessingModulePtr->echo_cancellation()->
|
|
enable_drift_compensation(true) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetEcStatus() failed to enable drift compensation");
|
|
return -1;
|
|
}
|
|
#else
|
|
if (_audioProcessingModulePtr->echo_cancellation()->
|
|
enable_drift_compensation(false) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetEcStatus() failed to disable drift compensation");
|
|
return -1;
|
|
}
|
|
#endif
|
|
if (mode == kEcConference)
|
|
{
|
|
if (_audioProcessingModulePtr->echo_cancellation()->
|
|
set_suppression_level(EchoCancellation::kHighSuppression) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetEcStatus() failed to set aggressiveness to high");
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_audioProcessingModulePtr->echo_cancellation()->
|
|
set_suppression_level(
|
|
EchoCancellation::kModerateSuppression) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetEcStatus() failed to set aggressiveness to moderate");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
_isAecMode = true;
|
|
}
|
|
else if ((mode == kEcAecm) ||
|
|
((mode == kEcUnchanged) &&
|
|
(_isAecMode == false)))
|
|
{
|
|
if (enable)
|
|
{
|
|
// Disable the AEC before enable the AECM
|
|
if (_audioProcessingModulePtr->echo_cancellation()->is_enabled())
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceWarning,
|
|
"SetEcStatus() disable AEC before enabling AECM");
|
|
if (_audioProcessingModulePtr->echo_cancellation()->
|
|
Enable(false) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetEcStatus() failed to disable AEC");
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
if (_audioProcessingModulePtr->echo_control_mobile()->
|
|
Enable(enable) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetEcStatus() failed to set AECM state");
|
|
return -1;
|
|
}
|
|
_isAecMode = false;
|
|
}
|
|
else
|
|
{
|
|
_engineStatistics.SetLastError(VE_INVALID_ARGUMENT, kTraceError,
|
|
"SetEcStatus() invalid EC mode");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetEcStatus() EC is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetEcStatus()");
|
|
#ifdef WEBRTC_VOICE_ENGINE_ECHO
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
if (_isAecMode == true)
|
|
{
|
|
mode = kEcAec;
|
|
enabled = _audioProcessingModulePtr->echo_cancellation()->is_enabled();
|
|
}
|
|
else
|
|
{
|
|
mode = kEcAecm;
|
|
enabled = _audioProcessingModulePtr->echo_control_mobile()->
|
|
is_enabled();
|
|
}
|
|
|
|
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetEcStatus() => enabled=%i, mode=%i",
|
|
enabled, (int)mode);
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"GetEcStatus() EC is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetAECMMode(mode = %d)", mode);
|
|
#ifdef WEBRTC_VOICE_ENGINE_ECHO
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
EchoControlMobile::RoutingMode aecmMode(
|
|
EchoControlMobile::kQuietEarpieceOrHeadset);
|
|
|
|
switch (mode)
|
|
{
|
|
case kAecmQuietEarpieceOrHeadset:
|
|
aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
|
|
break;
|
|
case kAecmEarpiece:
|
|
aecmMode = EchoControlMobile::kEarpiece;
|
|
break;
|
|
case kAecmLoudEarpiece:
|
|
aecmMode = EchoControlMobile::kLoudEarpiece;
|
|
break;
|
|
case kAecmSpeakerphone:
|
|
aecmMode = EchoControlMobile::kSpeakerphone;
|
|
break;
|
|
case kAecmLoudSpeakerphone:
|
|
aecmMode = EchoControlMobile::kLoudSpeakerphone;
|
|
break;
|
|
default:
|
|
_engineStatistics.SetLastError(VE_APM_ERROR, kTraceError,
|
|
"GetEcStatus() invalid EC mode");
|
|
return -1;
|
|
}
|
|
|
|
|
|
if (_audioProcessingModulePtr->echo_control_mobile()->
|
|
set_routing_mode(aecmMode) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetAECMMode() failed to set AECM routing mode");
|
|
return -1;
|
|
}
|
|
if (_audioProcessingModulePtr->echo_control_mobile()->
|
|
enable_comfort_noise(enableCNG) != 0)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetAECMMode() failed to set comfort noise state for AECM");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetAECMMode() EC is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetAECMMode(mode=?)");
|
|
#ifdef WEBRTC_VOICE_ENGINE_ECHO
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
enabledCNG = false;
|
|
|
|
EchoControlMobile::RoutingMode aecmMode =
|
|
_audioProcessingModulePtr->echo_control_mobile()->routing_mode();
|
|
enabledCNG = _audioProcessingModulePtr->echo_control_mobile()->
|
|
is_comfort_noise_enabled();
|
|
|
|
switch (aecmMode)
|
|
{
|
|
case EchoControlMobile::kQuietEarpieceOrHeadset:
|
|
mode = kAecmQuietEarpieceOrHeadset;
|
|
break;
|
|
case EchoControlMobile::kEarpiece:
|
|
mode = kAecmEarpiece;
|
|
break;
|
|
case EchoControlMobile::kLoudEarpiece:
|
|
mode = kAecmLoudEarpiece;
|
|
break;
|
|
case EchoControlMobile::kSpeakerphone:
|
|
mode = kAecmSpeakerphone;
|
|
break;
|
|
case EchoControlMobile::kLoudSpeakerphone:
|
|
mode = kAecmLoudSpeakerphone;
|
|
break;
|
|
default:
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"GetAECMMode() invalid EC mode");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"GetAECMMode() EC is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::RegisterRxVadObserver(
|
|
int channel,
|
|
VoERxVadCallback &observer)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"RegisterRxVadObserver()");
|
|
ANDROID_NOT_SUPPORTED();
|
|
IPHONE_NOT_SUPPORTED();
|
|
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
voe::ScopedChannel sc(_channelManager, channel);
|
|
voe::Channel* channelPtr = sc.ChannelPtr();
|
|
if (channelPtr == NULL)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_CHANNEL_NOT_VALID, kTraceError,
|
|
"RegisterRxVadObserver() failed to locate channel");
|
|
return -1;
|
|
}
|
|
return channelPtr->RegisterRxVadObserver(observer);
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::DeRegisterRxVadObserver(int channel)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"DeRegisterRxVadObserver()");
|
|
ANDROID_NOT_SUPPORTED();
|
|
IPHONE_NOT_SUPPORTED();
|
|
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
voe::ScopedChannel sc(_channelManager, channel);
|
|
voe::Channel* channelPtr = sc.ChannelPtr();
|
|
if (channelPtr == NULL)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_CHANNEL_NOT_VALID, kTraceError,
|
|
"DeRegisterRxVadObserver() failed to locate channel");
|
|
return -1;
|
|
}
|
|
|
|
return channelPtr->DeRegisterRxVadObserver();
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"VoiceActivityIndicator(channel=%d)", channel);
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
voe::ScopedChannel sc(_channelManager, channel);
|
|
voe::Channel* channelPtr = sc.ChannelPtr();
|
|
if (channelPtr == NULL)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_CHANNEL_NOT_VALID, kTraceError,
|
|
"DeRegisterRxVadObserver() failed to locate channel");
|
|
return -1;
|
|
}
|
|
int activity(-1);
|
|
channelPtr->VoiceActivityIndicator(activity);
|
|
|
|
return activity;
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetMetricsStatus(bool enable)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetMetricsStatus(enable=%d)", enable);
|
|
ANDROID_NOT_SUPPORTED();
|
|
IPHONE_NOT_SUPPORTED();
|
|
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
if ((_audioProcessingModulePtr->level_estimator()->Enable(enable)!= 0) ||
|
|
(_audioProcessingModulePtr->echo_cancellation()->enable_metrics(enable)
|
|
!= 0))
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"SetMetricsStatus() unable to set metrics mode");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetMetricsStatus(bool& enabled)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetMetricsStatus(enabled=?)");
|
|
ANDROID_NOT_SUPPORTED();
|
|
IPHONE_NOT_SUPPORTED();
|
|
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
bool levelMode =
|
|
_audioProcessingModulePtr->level_estimator()->is_enabled();
|
|
bool echoMode =
|
|
_audioProcessingModulePtr->echo_cancellation()->are_metrics_enabled();
|
|
|
|
if (levelMode != echoMode)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceError,
|
|
"GetMetricsStatus() level mode and echo mode are not the same");
|
|
return -1;
|
|
}
|
|
|
|
enabled = levelMode;
|
|
|
|
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetMetricsStatus() => enabled=%d", enabled);
|
|
return 0;
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetSpeechMetrics(int& levelTx, int& levelRx)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetSpeechMetrics(levelTx=?, levelRx=?)");
|
|
ANDROID_NOT_SUPPORTED();
|
|
IPHONE_NOT_SUPPORTED();
|
|
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
LevelEstimator::Metrics levelMetrics;
|
|
LevelEstimator::Metrics reverseLevelMetrics;
|
|
bool levelMode = _audioProcessingModulePtr->level_estimator()->is_enabled();
|
|
|
|
if (levelMode == false)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceWarning,
|
|
"GetSpeechMetrics() AudioProcessingModule level metrics is "
|
|
"not enabled");
|
|
return -1;
|
|
}
|
|
if (_audioProcessingModulePtr->level_estimator()->GetMetrics(
|
|
&levelMetrics, &reverseLevelMetrics))
|
|
{
|
|
WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetSpeechMetrics(), AudioProcessingModule level metrics"
|
|
" error");
|
|
return -1;
|
|
}
|
|
|
|
levelTx = levelMetrics.speech.instant;
|
|
levelRx = reverseLevelMetrics.speech.instant;
|
|
|
|
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetSpeechMetrics() => levelTx=%d, levelRx=%d",
|
|
levelTx, levelRx);
|
|
return 0;
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetNoiseMetrics(int& levelTx, int& levelRx)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetNoiseMetrics(levelTx=?, levelRx=?)");
|
|
ANDROID_NOT_SUPPORTED();
|
|
IPHONE_NOT_SUPPORTED();
|
|
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
bool levelMode =
|
|
_audioProcessingModulePtr->level_estimator()->is_enabled();
|
|
LevelEstimator::Metrics levelMetrics;
|
|
LevelEstimator::Metrics reverseLevelMetrics;
|
|
|
|
if (levelMode == false)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceWarning,
|
|
"GetNoiseMetrics() AudioProcessingModule level metrics is not"
|
|
"enabled");
|
|
return -1;
|
|
}
|
|
if (_audioProcessingModulePtr->level_estimator()->GetMetrics(
|
|
&levelMetrics, &reverseLevelMetrics))
|
|
{
|
|
WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetNoiseMetrics(), AudioProcessingModule level metrics"
|
|
" error");
|
|
return -1;
|
|
}
|
|
|
|
levelTx = levelMetrics.noise.instant;
|
|
levelRx = reverseLevelMetrics.noise.instant;
|
|
|
|
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetNoiseMetrics() => levelTx=%d, levelRx=%d", levelTx, levelRx);
|
|
return 0;
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
|
|
int& ERLE,
|
|
int& RERL,
|
|
int& A_NLP)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetEchoMetrics(ERL=?, ERLE=?, RERL=?, A_NLP=?)");
|
|
ANDROID_NOT_SUPPORTED();
|
|
IPHONE_NOT_SUPPORTED();
|
|
|
|
#ifdef WEBRTC_VOICE_ENGINE_ECHO
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
bool echoMode =
|
|
_audioProcessingModulePtr->echo_cancellation()->is_enabled();
|
|
EchoCancellation::Metrics echoMetrics;
|
|
|
|
if (echoMode == false)
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceWarning,
|
|
"GetEchoMetrics() AudioProcessingModule echo metrics is not"
|
|
"enabled");
|
|
return -1;
|
|
}
|
|
if (_audioProcessingModulePtr->echo_cancellation()->GetMetrics(
|
|
&echoMetrics))
|
|
{
|
|
WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetEchoMetrics(), AudioProcessingModule echo metrics"
|
|
"error");
|
|
return -1;
|
|
}
|
|
|
|
ERL = echoMetrics.echo_return_loss.instant;
|
|
ERLE = echoMetrics.echo_return_loss_enhancement.instant;
|
|
RERL = echoMetrics.residual_echo_return_loss.instant;
|
|
A_NLP = echoMetrics.a_nlp.instant;
|
|
|
|
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetEchoMetrics() => ERL=%d, ERLE=%d, RERL=%d, A_NLP=%d",
|
|
ERL, ERLE, RERL, A_NLP);
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetEcStatus() EC is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"StartDebugRecording()");
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
return _audioProcessingModulePtr->StartDebugRecording(fileNameUTF8);
|
|
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::StopDebugRecording()
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"StopDebugRecording()");
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
return _audioProcessingModulePtr->StopDebugRecording();
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"SetTypingDetectionStatus()");
|
|
ANDROID_NOT_SUPPORTED();
|
|
IPHONE_NOT_SUPPORTED();
|
|
#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
|
|
// Just use the VAD state to determine if we should enable typing detection
|
|
// or not
|
|
|
|
if (_audioProcessingModulePtr->voice_detection()->Enable(enable))
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceWarning,
|
|
"SetTypingDetectionStatus() failed to set VAD state");
|
|
return -1;
|
|
}
|
|
if (_audioProcessingModulePtr->voice_detection()->set_likelihood(
|
|
VoiceDetection::kHighLikelihood))
|
|
{
|
|
_engineStatistics.SetLastError(
|
|
VE_APM_ERROR, kTraceWarning,
|
|
"SetTypingDetectionStatus() failed to set VAD likelihood to high");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetTypingDetectionStatus is not supported");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled)
|
|
{
|
|
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
|
|
"GetTypingDetectionStatus()");
|
|
ANDROID_NOT_SUPPORTED();
|
|
IPHONE_NOT_SUPPORTED();
|
|
|
|
#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
|
|
if (!_engineStatistics.Initialized())
|
|
{
|
|
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
|
|
return -1;
|
|
}
|
|
// Just use the VAD state to determine if we should enable typing
|
|
// detection or not
|
|
|
|
enabled = _audioProcessingModulePtr->voice_detection()->is_enabled();
|
|
|
|
return(0);
|
|
#else
|
|
_engineStatistics.SetLastError(
|
|
VE_FUNC_NOT_SUPPORTED, kTraceError,
|
|
"SetTypingDetectionStatus is not supported");
|
|
return(-1);
|
|
#endif
|
|
}
|
|
|
|
#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
|
|
|
|
} // namespace webrtc
|