blob: c95726339ca3e86041006306830e32c6a962ed2c [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000011#include "webrtc/voice_engine/voe_audio_processing_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbosad856222015-11-27 09:48:36 -080013#include "webrtc/base/logging.h"
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000014#include "webrtc/modules/audio_processing/include/audio_processing.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010015#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010016#include "webrtc/system_wrappers/include/trace.h"
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000017#include "webrtc/voice_engine/channel.h"
18#include "webrtc/voice_engine/include/voe_errors.h"
19#include "webrtc/voice_engine/transmit_mixer.h"
20#include "webrtc/voice_engine/voice_engine_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000021
andrew@webrtc.org02d71742012-04-24 19:47:00 +000022// TODO(andrew): move to a common place.
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +000023#define WEBRTC_VOICE_INIT_CHECK() \
24 do { \
25 if (!_shared->statistics().Initialized()) { \
26 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
27 return -1; \
28 } \
29 } while (0)
30
31#define WEBRTC_VOICE_INIT_CHECK_BOOL() \
32 do { \
33 if (!_shared->statistics().Initialized()) { \
34 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
35 return false; \
36 } \
37 } while (0)
38
niklase@google.com470e71d2011-07-07 08:21:25 +000039namespace webrtc {
40
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +000041#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
andrew@webrtc.org80124742012-03-08 17:54:24 +000042static const EcModes kDefaultEcMode = kEcAecm;
43#else
44static const EcModes kDefaultEcMode = kEcAec;
45#endif
46
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000047VoEAudioProcessing* VoEAudioProcessing::GetInterface(VoiceEngine* voiceEngine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000048#ifndef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000049 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000050#else
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000051 if (NULL == voiceEngine) {
52 return NULL;
53 }
tommi@webrtc.org0989fb72013-02-15 15:07:32 +000054 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
tommi@webrtc.orga990e122012-04-26 15:28:22 +000055 s->AddRef();
56 return s;
niklase@google.com470e71d2011-07-07 08:21:25 +000057#endif
58}
59
60#ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
tommi@webrtc.org851becd2012-04-04 14:57:19 +000061VoEAudioProcessingImpl::VoEAudioProcessingImpl(voe::SharedData* shared)
Jelena Marusic0d266052015-05-04 14:15:32 +020062 : _isAecMode(kDefaultEcMode == kEcAec), _shared(shared) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000063 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000064 "VoEAudioProcessingImpl::VoEAudioProcessingImpl() - ctor");
niklase@google.com470e71d2011-07-07 08:21:25 +000065}
66
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000067VoEAudioProcessingImpl::~VoEAudioProcessingImpl() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000068 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000069 "VoEAudioProcessingImpl::~VoEAudioProcessingImpl() - dtor");
niklase@google.com470e71d2011-07-07 08:21:25 +000070}
71
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000072int VoEAudioProcessingImpl::SetNsStatus(bool enable, NsModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000073 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000074 "SetNsStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +000075#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +000076 if (!_shared->statistics().Initialized()) {
77 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000078 return -1;
79 }
niklase@google.com470e71d2011-07-07 08:21:25 +000080
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000081 NoiseSuppression::Level nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000082 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000083 case kNsDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000084 nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000085 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000086 case kNsUnchanged:
tommi@webrtc.org851becd2012-04-04 14:57:19 +000087 nsLevel = _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000088 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000089 case kNsConference:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000090 nsLevel = NoiseSuppression::kHigh;
91 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000092 case kNsLowSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000093 nsLevel = NoiseSuppression::kLow;
94 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000095 case kNsModerateSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000096 nsLevel = NoiseSuppression::kModerate;
97 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000098 case kNsHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000099 nsLevel = NoiseSuppression::kHigh;
100 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000101 case kNsVeryHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000102 nsLevel = NoiseSuppression::kVeryHigh;
103 break;
104 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000105
Jelena Marusic0d266052015-05-04 14:15:32 +0200106 if (_shared->audio_processing()->noise_suppression()->set_level(nsLevel) !=
107 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000108 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200109 "SetNsStatus() failed to set Ns mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000110 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000111 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000112 if (_shared->audio_processing()->noise_suppression()->Enable(enable) != 0) {
113 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200114 "SetNsStatus() failed to set Ns state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000115 return -1;
116 }
117
118 return 0;
119#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000120 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200121 "SetNsStatus() Ns is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000122 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000123#endif
124}
125
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000126int VoEAudioProcessingImpl::GetNsStatus(bool& enabled, NsModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000127#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000128 if (!_shared->statistics().Initialized()) {
129 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000130 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000131 }
132
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000133 enabled = _shared->audio_processing()->noise_suppression()->is_enabled();
134 NoiseSuppression::Level nsLevel =
135 _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000136
137 switch (nsLevel) {
138 case NoiseSuppression::kLow:
139 mode = kNsLowSuppression;
140 break;
141 case NoiseSuppression::kModerate:
142 mode = kNsModerateSuppression;
143 break;
144 case NoiseSuppression::kHigh:
145 mode = kNsHighSuppression;
146 break;
147 case NoiseSuppression::kVeryHigh:
148 mode = kNsVeryHighSuppression;
149 break;
150 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000151 return 0;
152#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000153 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200154 "GetNsStatus() Ns is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000155 return -1;
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000156#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000157}
158
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000159int VoEAudioProcessingImpl::SetAgcStatus(bool enable, AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000160 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000161 "SetAgcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000162#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000163 if (!_shared->statistics().Initialized()) {
164 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000165 return -1;
166 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000167
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000168#if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000169 if (mode == kAgcAdaptiveAnalog) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000170 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200171 "SetAgcStatus() invalid Agc mode for mobile device");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000172 return -1;
173 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000174#endif
175
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000176 GainControl::Mode agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000177 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000178 case kAgcDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000179 agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000180 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000181 case kAgcUnchanged:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000182 agcMode = _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000183 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000184 case kAgcFixedDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000185 agcMode = GainControl::kFixedDigital;
186 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000187 case kAgcAdaptiveAnalog:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000188 agcMode = GainControl::kAdaptiveAnalog;
189 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000190 case kAgcAdaptiveDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000191 agcMode = GainControl::kAdaptiveDigital;
192 break;
193 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000194
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000195 if (_shared->audio_processing()->gain_control()->set_mode(agcMode) != 0) {
196 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200197 "SetAgcStatus() failed to set Agc mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000198 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000199 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000200 if (_shared->audio_processing()->gain_control()->Enable(enable) != 0) {
201 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200202 "SetAgcStatus() failed to set Agc state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000203 return -1;
204 }
205
206 if (agcMode != GainControl::kFixedDigital) {
207 // Set Agc state in the ADM when adaptive Agc mode has been selected.
208 // Note that we also enable the ADM Agc when Adaptive Digital mode is
209 // used since we want to be able to provide the APM with updated mic
210 // levels when the user modifies the mic level manually.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000211 if (_shared->audio_device()->SetAGC(enable) != 0) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200212 _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning,
213 "SetAgcStatus() failed to set Agc mode");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000214 }
215 }
216
217 return 0;
218#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000219 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200220 "SetAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000221 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000222#endif
223}
224
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000225int VoEAudioProcessingImpl::GetAgcStatus(bool& enabled, AgcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000226#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000227 if (!_shared->statistics().Initialized()) {
228 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000229 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000230 }
231
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000232 enabled = _shared->audio_processing()->gain_control()->is_enabled();
sjlee@webrtc.orgb4c441a2013-03-25 11:12:20 +0000233 GainControl::Mode agcMode =
Jelena Marusic0d266052015-05-04 14:15:32 +0200234 _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000235
236 switch (agcMode) {
237 case GainControl::kFixedDigital:
238 mode = kAgcFixedDigital;
239 break;
240 case GainControl::kAdaptiveAnalog:
241 mode = kAgcAdaptiveAnalog;
242 break;
243 case GainControl::kAdaptiveDigital:
244 mode = kAgcAdaptiveDigital;
245 break;
246 }
247
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000248 return 0;
249#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000250 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200251 "GetAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000252 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000253#endif
254}
255
pbos@webrtc.org92135212013-05-14 08:31:39 +0000256int VoEAudioProcessingImpl::SetAgcConfig(AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000257 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000258 "SetAgcConfig()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000259#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000260 if (!_shared->statistics().Initialized()) {
261 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000262 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000263 }
264
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000265 if (_shared->audio_processing()->gain_control()->set_target_level_dbfs(
Jelena Marusic0d266052015-05-04 14:15:32 +0200266 config.targetLeveldBOv) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000267 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200268 "SetAgcConfig() failed to set target peak |level|"
269 " (or envelope) of the Agc");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000270 return -1;
271 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000272 if (_shared->audio_processing()->gain_control()->set_compression_gain_db(
Jelena Marusic0d266052015-05-04 14:15:32 +0200273 config.digitalCompressionGaindB) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000274 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200275 "SetAgcConfig() failed to set the range in |gain| "
276 "the digital compression stage may apply");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000277 return -1;
278 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000279 if (_shared->audio_processing()->gain_control()->enable_limiter(
Jelena Marusic0d266052015-05-04 14:15:32 +0200280 config.limiterEnable) != 0) {
281 _shared->SetLastError(
282 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000283 "SetAgcConfig() failed to set hard limiter to the signal");
284 return -1;
285 }
286
287 return 0;
288#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000289 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200290 "SetAgcConfig() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000291 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000292#endif
293}
294
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000295int VoEAudioProcessingImpl::GetAgcConfig(AgcConfig& config) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000296#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000297 if (!_shared->statistics().Initialized()) {
298 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000299 return -1;
300 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000301
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000302 config.targetLeveldBOv =
Jelena Marusic0d266052015-05-04 14:15:32 +0200303 _shared->audio_processing()->gain_control()->target_level_dbfs();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000304 config.digitalCompressionGaindB =
Jelena Marusic0d266052015-05-04 14:15:32 +0200305 _shared->audio_processing()->gain_control()->compression_gain_db();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000306 config.limiterEnable =
Jelena Marusic0d266052015-05-04 14:15:32 +0200307 _shared->audio_processing()->gain_control()->is_limiter_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000308
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000309 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000310#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000311 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200312 "GetAgcConfig() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000313 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000314#endif
315}
316
317int VoEAudioProcessingImpl::SetRxNsStatus(int channel,
318 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000319 NsModes mode) {
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000320#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000321 if (!_shared->statistics().Initialized()) {
322 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000323 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000324 }
325
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000326 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
327 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000328 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000329 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200330 "SetRxNsStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000331 return -1;
332 }
333 return channelPtr->SetRxNsStatus(enable, mode);
334#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000335 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200336 "SetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000337 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000338#endif
339}
340
341int VoEAudioProcessingImpl::GetRxNsStatus(int channel,
342 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000343 NsModes& mode) {
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000344#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000345 if (!_shared->statistics().Initialized()) {
346 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000347 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000348 }
349
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000350 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
351 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000352 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000353 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200354 "GetRxNsStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000355 return -1;
356 }
357 return channelPtr->GetRxNsStatus(enabled, mode);
358#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000359 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200360 "GetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000361 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000362#endif
363}
364
365int VoEAudioProcessingImpl::SetRxAgcStatus(int channel,
366 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000367 AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000368 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
Jelena Marusic0d266052015-05-04 14:15:32 +0200369 "SetRxAgcStatus(channel=%d, enable=%d, mode=%d)", channel,
370 (int)enable, (int)mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000371#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000372 if (!_shared->statistics().Initialized()) {
373 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000374 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000375 }
376
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000377 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
378 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000379 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000380 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200381 "SetRxAgcStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000382 return -1;
383 }
384 return channelPtr->SetRxAgcStatus(enable, mode);
385#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000386 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200387 "SetRxAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000388 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000389#endif
390}
391
392int VoEAudioProcessingImpl::GetRxAgcStatus(int channel,
393 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000394 AgcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000395#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000396 if (!_shared->statistics().Initialized()) {
397 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000398 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000399 }
400
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000401 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
402 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000403 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000404 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200405 "GetRxAgcStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000406 return -1;
407 }
408 return channelPtr->GetRxAgcStatus(enabled, mode);
409#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000410 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200411 "GetRxAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000412 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000413#endif
414}
415
Jelena Marusic0d266052015-05-04 14:15:32 +0200416int VoEAudioProcessingImpl::SetRxAgcConfig(int channel, AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000417 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000418 "SetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000419#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000420 if (!_shared->statistics().Initialized()) {
421 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000422 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000423 }
424
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000425 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
426 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000427 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000428 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200429 "SetRxAgcConfig() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000430 return -1;
431 }
432 return channelPtr->SetRxAgcConfig(config);
433#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000434 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200435 "SetRxAgcConfig() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000436 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000437#endif
438}
439
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000440int VoEAudioProcessingImpl::GetRxAgcConfig(int channel, AgcConfig& config) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000441#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000442 if (!_shared->statistics().Initialized()) {
443 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000444 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000445 }
446
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000447 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
448 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000449 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000450 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200451 "GetRxAgcConfig() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000452 return -1;
453 }
454 return channelPtr->GetRxAgcConfig(config);
455#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000456 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200457 "GetRxAgcConfig() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000458 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000459#endif
460}
461
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000462bool VoEAudioProcessing::DriftCompensationSupported() {
463#if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
464 return true;
465#else
466 return false;
467#endif
468}
469
470int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000471 WEBRTC_VOICE_INIT_CHECK();
472
473 if (!DriftCompensationSupported()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200474 _shared->SetLastError(
475 VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000476 "Drift compensation is not supported on this platform.");
477 return -1;
478 }
479
480 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
481 if (aec->enable_drift_compensation(enable) != 0) {
482 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200483 "aec->enable_drift_compensation() failed");
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000484 return -1;
485 }
486 return 0;
487}
488
489bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000490 WEBRTC_VOICE_INIT_CHECK_BOOL();
491
492 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
493 return aec->is_drift_compensation_enabled();
494}
495
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000496int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000497 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000498 "SetEcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000499#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000500 if (!_shared->statistics().Initialized()) {
501 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000502 return -1;
503 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000504
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000505 // AEC mode
Jelena Marusic0d266052015-05-04 14:15:32 +0200506 if ((mode == kEcDefault) || (mode == kEcConference) || (mode == kEcAec) ||
507 ((mode == kEcUnchanged) && (_isAecMode == true))) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000508 if (enable) {
509 // Disable the AECM before enable the AEC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000510 if (_shared->audio_processing()->echo_control_mobile()->is_enabled()) {
511 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200512 "SetEcStatus() disable AECM before enabling AEC");
513 if (_shared->audio_processing()->echo_control_mobile()->Enable(false) !=
514 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000515 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200516 "SetEcStatus() failed to disable AECM");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000517 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000518 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000519 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000520 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000521 if (_shared->audio_processing()->echo_cancellation()->Enable(enable) != 0) {
522 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200523 "SetEcStatus() failed to set AEC state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000524 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000525 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000526 if (mode == kEcConference) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200527 if (_shared->audio_processing()
528 ->echo_cancellation()
529 ->set_suppression_level(EchoCancellation::kHighSuppression) !=
530 0) {
531 _shared->SetLastError(
532 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000533 "SetEcStatus() failed to set aggressiveness to high");
niklase@google.com470e71d2011-07-07 08:21:25 +0000534 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000535 }
536 } else {
Jelena Marusic0d266052015-05-04 14:15:32 +0200537 if (_shared->audio_processing()
538 ->echo_cancellation()
539 ->set_suppression_level(EchoCancellation::kModerateSuppression) !=
540 0) {
541 _shared->SetLastError(
542 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000543 "SetEcStatus() failed to set aggressiveness to moderate");
niklase@google.com470e71d2011-07-07 08:21:25 +0000544 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000545 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000546 }
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000547
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000548 _isAecMode = true;
549 } else if ((mode == kEcAecm) ||
Jelena Marusic0d266052015-05-04 14:15:32 +0200550 ((mode == kEcUnchanged) && (_isAecMode == false))) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000551 if (enable) {
552 // Disable the AEC before enable the AECM
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000553 if (_shared->audio_processing()->echo_cancellation()->is_enabled()) {
554 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200555 "SetEcStatus() disable AEC before enabling AECM");
556 if (_shared->audio_processing()->echo_cancellation()->Enable(false) !=
557 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000558 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200559 "SetEcStatus() failed to disable AEC");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000560 return -1;
561 }
562 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000563 }
Jelena Marusic0d266052015-05-04 14:15:32 +0200564 if (_shared->audio_processing()->echo_control_mobile()->Enable(enable) !=
565 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000566 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200567 "SetEcStatus() failed to set AECM state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000568 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000569 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000570 _isAecMode = false;
571 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000572 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200573 "SetEcStatus() invalid EC mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000574 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000575 }
576
577 return 0;
578#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000579 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200580 "SetEcStatus() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000581 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000582#endif
583}
584
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000585int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000586#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000587 if (!_shared->statistics().Initialized()) {
588 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000589 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000590 }
591
592 if (_isAecMode == true) {
593 mode = kEcAec;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000594 enabled = _shared->audio_processing()->echo_cancellation()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000595 } else {
596 mode = kEcAecm;
Jelena Marusic0d266052015-05-04 14:15:32 +0200597 enabled = _shared->audio_processing()->echo_control_mobile()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000598 }
599
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000600 return 0;
601#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000602 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200603 "GetEcStatus() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000604 return -1;
605#endif
606}
607
608void VoEAudioProcessingImpl::SetDelayOffsetMs(int offset) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000609 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000610 "SetDelayOffsetMs(offset = %d)", offset);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000611 _shared->audio_processing()->set_delay_offset_ms(offset);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000612}
613
614int VoEAudioProcessingImpl::DelayOffsetMs() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000615 return _shared->audio_processing()->delay_offset_ms();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000616}
617
618int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000619 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000620 "SetAECMMode(mode = %d)", mode);
621#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000622 if (!_shared->statistics().Initialized()) {
623 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000624 return -1;
625 }
626
627 EchoControlMobile::RoutingMode aecmMode(
628 EchoControlMobile::kQuietEarpieceOrHeadset);
629
630 switch (mode) {
631 case kAecmQuietEarpieceOrHeadset:
632 aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
633 break;
634 case kAecmEarpiece:
635 aecmMode = EchoControlMobile::kEarpiece;
636 break;
637 case kAecmLoudEarpiece:
638 aecmMode = EchoControlMobile::kLoudEarpiece;
639 break;
640 case kAecmSpeakerphone:
641 aecmMode = EchoControlMobile::kSpeakerphone;
642 break;
643 case kAecmLoudSpeakerphone:
644 aecmMode = EchoControlMobile::kLoudSpeakerphone;
645 break;
646 }
647
Jelena Marusic0d266052015-05-04 14:15:32 +0200648 if (_shared->audio_processing()->echo_control_mobile()->set_routing_mode(
649 aecmMode) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000650 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200651 "SetAECMMode() failed to set AECM routing mode");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000652 return -1;
653 }
Jelena Marusic0d266052015-05-04 14:15:32 +0200654 if (_shared->audio_processing()->echo_control_mobile()->enable_comfort_noise(
655 enableCNG) != 0) {
656 _shared->SetLastError(
657 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000658 "SetAECMMode() failed to set comfort noise state for AECM");
659 return -1;
660 }
661
662 return 0;
663#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000664 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200665 "SetAECMMode() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000666 return -1;
667#endif
668}
669
670int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000671#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000672 if (!_shared->statistics().Initialized()) {
673 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000674 return -1;
675 }
676
677 enabledCNG = false;
678
679 EchoControlMobile::RoutingMode aecmMode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000680 _shared->audio_processing()->echo_control_mobile()->routing_mode();
Jelena Marusic0d266052015-05-04 14:15:32 +0200681 enabledCNG = _shared->audio_processing()
682 ->echo_control_mobile()
683 ->is_comfort_noise_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000684
685 switch (aecmMode) {
686 case EchoControlMobile::kQuietEarpieceOrHeadset:
687 mode = kAecmQuietEarpieceOrHeadset;
688 break;
689 case EchoControlMobile::kEarpiece:
690 mode = kAecmEarpiece;
691 break;
692 case EchoControlMobile::kLoudEarpiece:
693 mode = kAecmLoudEarpiece;
694 break;
695 case EchoControlMobile::kSpeakerphone:
696 mode = kAecmSpeakerphone;
697 break;
698 case EchoControlMobile::kLoudSpeakerphone:
699 mode = kAecmLoudSpeakerphone;
700 break;
701 }
702
703 return 0;
704#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000705 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200706 "GetAECMMode() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000707 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000708#endif
709}
710
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000711int VoEAudioProcessingImpl::EnableHighPassFilter(bool enable) {
712 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
713 "EnableHighPassFilter(%d)", enable);
714 if (_shared->audio_processing()->high_pass_filter()->Enable(enable) !=
715 AudioProcessing::kNoError) {
716 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200717 "HighPassFilter::Enable() failed.");
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000718 return -1;
719 }
720
721 return 0;
722}
723
724bool VoEAudioProcessingImpl::IsHighPassFilterEnabled() {
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000725 return _shared->audio_processing()->high_pass_filter()->is_enabled();
726}
727
Jelena Marusic0d266052015-05-04 14:15:32 +0200728int VoEAudioProcessingImpl::RegisterRxVadObserver(int channel,
729 VoERxVadCallback& observer) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000730 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000731 "RegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000732 if (!_shared->statistics().Initialized()) {
733 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000734 return -1;
735 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000736 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
737 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000738 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000739 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200740 "RegisterRxVadObserver() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000741 return -1;
742 }
743 return channelPtr->RegisterRxVadObserver(observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000744}
745
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000746int VoEAudioProcessingImpl::DeRegisterRxVadObserver(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000747 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000748 "DeRegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000749 if (!_shared->statistics().Initialized()) {
750 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000751 return -1;
752 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000753 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
754 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000755 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000756 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200757 "DeRegisterRxVadObserver() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000758 return -1;
759 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000760
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000761 return channelPtr->DeRegisterRxVadObserver();
niklase@google.com470e71d2011-07-07 08:21:25 +0000762}
763
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000764int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000765 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000766 "VoiceActivityIndicator(channel=%d)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000767 if (!_shared->statistics().Initialized()) {
768 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000769 return -1;
770 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000771
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000772 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
773 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000774 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000775 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200776 "DeRegisterRxVadObserver() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000777 return -1;
778 }
779 int activity(-1);
780 channelPtr->VoiceActivityIndicator(activity);
niklase@google.com470e71d2011-07-07 08:21:25 +0000781
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000782 return activity;
niklase@google.com470e71d2011-07-07 08:21:25 +0000783}
784
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000785int VoEAudioProcessingImpl::SetEcMetricsStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000786 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000787 "SetEcMetricsStatus(enable=%d)", enable);
bjornv@google.com0beae672011-09-28 14:08:19 +0000788#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000789 if (!_shared->statistics().Initialized()) {
790 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000791 return -1;
792 }
793
Jelena Marusic0d266052015-05-04 14:15:32 +0200794 if ((_shared->audio_processing()->echo_cancellation()->enable_metrics(
795 enable) != 0) ||
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000796 (_shared->audio_processing()->echo_cancellation()->enable_delay_logging(
Jelena Marusic0d266052015-05-04 14:15:32 +0200797 enable) != 0)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000798 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200799 "SetEcMetricsStatus() unable to set EC metrics mode");
bjornv@google.com0beae672011-09-28 14:08:19 +0000800 return -1;
801 }
802 return 0;
803#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000804 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200805 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000806 return -1;
807#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000808}
809
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000810int VoEAudioProcessingImpl::GetEcMetricsStatus(bool& enabled) {
bjornv@google.com0beae672011-09-28 14:08:19 +0000811#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000812 if (!_shared->statistics().Initialized()) {
813 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000814 return -1;
815 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000816
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000817 bool echo_mode =
Jelena Marusic0d266052015-05-04 14:15:32 +0200818 _shared->audio_processing()->echo_cancellation()->are_metrics_enabled();
819 bool delay_mode = _shared->audio_processing()
820 ->echo_cancellation()
821 ->is_delay_logging_enabled();
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000822
823 if (echo_mode != delay_mode) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200824 _shared->SetLastError(
825 VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000826 "GetEcMetricsStatus() delay logging and echo mode are not the same");
827 return -1;
828 }
829
830 enabled = echo_mode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000831
bjornv@google.com0beae672011-09-28 14:08:19 +0000832 return 0;
833#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000834 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200835 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000836 return -1;
837#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000838}
839
840int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
841 int& ERLE,
842 int& RERL,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000843 int& A_NLP) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000844#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000845 if (!_shared->statistics().Initialized()) {
846 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000847 return -1;
848 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000849 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200850 _shared->SetLastError(
851 VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000852 "GetEchoMetrics() AudioProcessingModule AEC is not enabled");
853 return -1;
854 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000855
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000856 // Get Echo Metrics from Audio Processing Module.
857 EchoCancellation::Metrics echoMetrics;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000858 if (_shared->audio_processing()->echo_cancellation()->GetMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000859 &echoMetrics)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000860 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000861 "GetEchoMetrics(), AudioProcessingModule metrics error");
862 return -1;
863 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000864
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000865 // Echo quality metrics.
866 ERL = echoMetrics.echo_return_loss.instant;
867 ERLE = echoMetrics.echo_return_loss_enhancement.instant;
868 RERL = echoMetrics.residual_echo_return_loss.instant;
869 A_NLP = echoMetrics.a_nlp.instant;
niklase@google.com470e71d2011-07-07 08:21:25 +0000870
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000871 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000872#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000873 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200874 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000875 return -1;
876#endif
877}
878
879int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median,
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000880 int& delay_std,
881 float& fraction_poor_delays) {
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000882#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000883 if (!_shared->statistics().Initialized()) {
884 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000885 return -1;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000886 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000887 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200888 _shared->SetLastError(
889 VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000890 "GetEcDelayMetrics() AudioProcessingModule AEC is not enabled");
891 return -1;
892 }
893
894 int median = 0;
895 int std = 0;
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000896 float poor_fraction = 0;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000897 // Get delay-logging values from Audio Processing Module.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000898 if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics(
Jelena Marusic0d266052015-05-04 14:15:32 +0200899 &median, &std, &poor_fraction)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000900 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000901 "GetEcDelayMetrics(), AudioProcessingModule delay-logging "
902 "error");
903 return -1;
904 }
905
906 // EC delay-logging metrics
907 delay_median = median;
908 delay_std = std;
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000909 fraction_poor_delays = poor_fraction;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000910
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000911 return 0;
912#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000913 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200914 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000915 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000916#endif
917}
918
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000919int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000920 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000921 "StartDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000922 if (!_shared->statistics().Initialized()) {
923 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000924 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000925 }
926
ivoca4df27b2015-12-19 10:14:10 -0800927 return _shared->audio_processing()->StartDebugRecording(fileNameUTF8);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000928}
929
henrikg@webrtc.org863b5362013-12-06 16:05:17 +0000930int VoEAudioProcessingImpl::StartDebugRecording(FILE* file_handle) {
931 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
932 "StartDebugRecording()");
933 if (!_shared->statistics().Initialized()) {
934 _shared->SetLastError(VE_NOT_INITED, kTraceError);
935 return -1;
936 }
937
ivoca4df27b2015-12-19 10:14:10 -0800938 return _shared->audio_processing()->StartDebugRecording(file_handle);
henrikg@webrtc.org863b5362013-12-06 16:05:17 +0000939}
940
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000941int VoEAudioProcessingImpl::StopDebugRecording() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000942 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000943 "StopDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000944 if (!_shared->statistics().Initialized()) {
945 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000946 return -1;
947 }
948
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000949 return _shared->audio_processing()->StopDebugRecording();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000950}
951
952int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000953 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000954 "SetTypingDetectionStatus()");
andrew@webrtc.org0851df82013-06-19 17:03:47 +0000955#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
956 NOT_SUPPORTED(_shared->statistics());
957#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000958 if (!_shared->statistics().Initialized()) {
959 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000960 return -1;
961 }
962
963 // Just use the VAD state to determine if we should enable typing detection
964 // or not
965
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000966 if (_shared->audio_processing()->voice_detection()->Enable(enable)) {
967 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200968 "SetTypingDetectionStatus() failed to set VAD state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000969 return -1;
970 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000971 if (_shared->audio_processing()->voice_detection()->set_likelihood(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000972 VoiceDetection::kVeryLowLikelihood)) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200973 _shared->SetLastError(
974 VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000975 "SetTypingDetectionStatus() failed to set VAD likelihood to low");
976 return -1;
977 }
978
979 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000980#endif
981}
982
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000983int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000984 if (!_shared->statistics().Initialized()) {
985 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000986 return -1;
987 }
988 // Just use the VAD state to determine if we should enable typing
989 // detection or not
niklase@google.com470e71d2011-07-07 08:21:25 +0000990
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000991 enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000992
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000993 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000994}
995
Jelena Marusic0d266052015-05-04 14:15:32 +0200996int VoEAudioProcessingImpl::TimeSinceLastTyping(int& seconds) {
andrew@webrtc.org0851df82013-06-19 17:03:47 +0000997#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
998 NOT_SUPPORTED(_shared->statistics());
999#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001000 if (!_shared->statistics().Initialized()) {
1001 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001002 return -1;
1003 }
1004 // Check if typing detection is enabled
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001005 bool enabled = _shared->audio_processing()->voice_detection()->is_enabled();
Jelena Marusic0d266052015-05-04 14:15:32 +02001006 if (enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001007 _shared->transmit_mixer()->TimeSinceLastTyping(seconds);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001008 return 0;
Jelena Marusic0d266052015-05-04 14:15:32 +02001009 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001010 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +02001011 "SetTypingDetectionStatus is not enabled");
1012 return -1;
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001013 }
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001014#endif
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001015}
1016
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001017int VoEAudioProcessingImpl::SetTypingDetectionParameters(int timeWindow,
1018 int costPerTyping,
1019 int reportingThreshold,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001020 int penaltyDecay,
1021 int typeEventDelay) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001022 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001023 "SetTypingDetectionParameters()");
andrew@webrtc.org0851df82013-06-19 17:03:47 +00001024#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
1025 NOT_SUPPORTED(_shared->statistics());
1026#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001027 if (!_shared->statistics().Initialized()) {
1028 _shared->statistics().SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001029 return -1;
1030 }
Jelena Marusic0d266052015-05-04 14:15:32 +02001031 return (_shared->transmit_mixer()->SetTypingDetectionParameters(
1032 timeWindow, costPerTyping, reportingThreshold, penaltyDecay,
1033 typeEventDelay));
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001034#endif
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001035}
1036
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001037void VoEAudioProcessingImpl::EnableStereoChannelSwapping(bool enable) {
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001038 _shared->transmit_mixer()->EnableStereoChannelSwapping(enable);
1039}
1040
1041bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001042 return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
1043}
1044
niklase@google.com470e71d2011-07-07 08:21:25 +00001045#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
1046
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001047} // namespace webrtc