blob: 83f70fe68e62d70c6b657460adfac761cc8e343b [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
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000013#include "webrtc/modules/audio_processing/include/audio_processing.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010014#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
15#include "webrtc/system_wrappers/include/logging.h"
16#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.org50419b02012-11-14 19:07:54 +0000320 LOG_API3(channel, enable, mode);
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000321#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000322 if (!_shared->statistics().Initialized()) {
323 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000324 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000325 }
326
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000327 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
328 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000329 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000330 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200331 "SetRxNsStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000332 return -1;
333 }
334 return channelPtr->SetRxNsStatus(enable, mode);
335#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000336 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200337 "SetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000338 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000339#endif
340}
341
342int VoEAudioProcessingImpl::GetRxNsStatus(int channel,
343 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000344 NsModes& mode) {
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000345#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000346 if (!_shared->statistics().Initialized()) {
347 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000348 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000349 }
350
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000351 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
352 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000353 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000354 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200355 "GetRxNsStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000356 return -1;
357 }
358 return channelPtr->GetRxNsStatus(enabled, mode);
359#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000360 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200361 "GetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000362 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000363#endif
364}
365
366int VoEAudioProcessingImpl::SetRxAgcStatus(int channel,
367 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000368 AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000369 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
Jelena Marusic0d266052015-05-04 14:15:32 +0200370 "SetRxAgcStatus(channel=%d, enable=%d, mode=%d)", channel,
371 (int)enable, (int)mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000372#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000373 if (!_shared->statistics().Initialized()) {
374 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000375 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000376 }
377
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000378 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
379 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000380 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000381 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200382 "SetRxAgcStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000383 return -1;
384 }
385 return channelPtr->SetRxAgcStatus(enable, mode);
386#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000387 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200388 "SetRxAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000389 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000390#endif
391}
392
393int VoEAudioProcessingImpl::GetRxAgcStatus(int channel,
394 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000395 AgcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000396#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000397 if (!_shared->statistics().Initialized()) {
398 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000399 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000400 }
401
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000402 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
403 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000404 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000405 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200406 "GetRxAgcStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000407 return -1;
408 }
409 return channelPtr->GetRxAgcStatus(enabled, mode);
410#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000411 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200412 "GetRxAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000413 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000414#endif
415}
416
Jelena Marusic0d266052015-05-04 14:15:32 +0200417int VoEAudioProcessingImpl::SetRxAgcConfig(int channel, AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000418 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000419 "SetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000420#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000421 if (!_shared->statistics().Initialized()) {
422 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000423 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000424 }
425
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000426 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
427 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000428 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000429 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200430 "SetRxAgcConfig() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000431 return -1;
432 }
433 return channelPtr->SetRxAgcConfig(config);
434#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000435 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200436 "SetRxAgcConfig() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000437 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000438#endif
439}
440
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000441int VoEAudioProcessingImpl::GetRxAgcConfig(int channel, AgcConfig& config) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000442#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000443 if (!_shared->statistics().Initialized()) {
444 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000445 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000446 }
447
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000448 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
449 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000450 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000451 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200452 "GetRxAgcConfig() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000453 return -1;
454 }
455 return channelPtr->GetRxAgcConfig(config);
456#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000457 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200458 "GetRxAgcConfig() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000459 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000460#endif
461}
462
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000463bool VoEAudioProcessing::DriftCompensationSupported() {
464#if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
465 return true;
466#else
467 return false;
468#endif
469}
470
471int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000472 LOG_API1(enable);
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000473 WEBRTC_VOICE_INIT_CHECK();
474
475 if (!DriftCompensationSupported()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200476 _shared->SetLastError(
477 VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000478 "Drift compensation is not supported on this platform.");
479 return -1;
480 }
481
482 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
483 if (aec->enable_drift_compensation(enable) != 0) {
484 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200485 "aec->enable_drift_compensation() failed");
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000486 return -1;
487 }
488 return 0;
489}
490
491bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000492 LOG_API0();
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000493 WEBRTC_VOICE_INIT_CHECK_BOOL();
494
495 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
496 return aec->is_drift_compensation_enabled();
497}
498
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000499int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000500 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000501 "SetEcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000502#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000503 if (!_shared->statistics().Initialized()) {
504 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000505 return -1;
506 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000507
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000508 // AEC mode
Jelena Marusic0d266052015-05-04 14:15:32 +0200509 if ((mode == kEcDefault) || (mode == kEcConference) || (mode == kEcAec) ||
510 ((mode == kEcUnchanged) && (_isAecMode == true))) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000511 if (enable) {
512 // Disable the AECM before enable the AEC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000513 if (_shared->audio_processing()->echo_control_mobile()->is_enabled()) {
514 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200515 "SetEcStatus() disable AECM before enabling AEC");
516 if (_shared->audio_processing()->echo_control_mobile()->Enable(false) !=
517 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000518 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200519 "SetEcStatus() failed to disable AECM");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000520 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000521 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000522 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000523 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000524 if (_shared->audio_processing()->echo_cancellation()->Enable(enable) != 0) {
525 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200526 "SetEcStatus() failed to set AEC state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000527 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000528 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000529 if (mode == kEcConference) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200530 if (_shared->audio_processing()
531 ->echo_cancellation()
532 ->set_suppression_level(EchoCancellation::kHighSuppression) !=
533 0) {
534 _shared->SetLastError(
535 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000536 "SetEcStatus() failed to set aggressiveness to high");
niklase@google.com470e71d2011-07-07 08:21:25 +0000537 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000538 }
539 } else {
Jelena Marusic0d266052015-05-04 14:15:32 +0200540 if (_shared->audio_processing()
541 ->echo_cancellation()
542 ->set_suppression_level(EchoCancellation::kModerateSuppression) !=
543 0) {
544 _shared->SetLastError(
545 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000546 "SetEcStatus() failed to set aggressiveness to moderate");
niklase@google.com470e71d2011-07-07 08:21:25 +0000547 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000548 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000549 }
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000550
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000551 _isAecMode = true;
552 } else if ((mode == kEcAecm) ||
Jelena Marusic0d266052015-05-04 14:15:32 +0200553 ((mode == kEcUnchanged) && (_isAecMode == false))) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000554 if (enable) {
555 // Disable the AEC before enable the AECM
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000556 if (_shared->audio_processing()->echo_cancellation()->is_enabled()) {
557 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200558 "SetEcStatus() disable AEC before enabling AECM");
559 if (_shared->audio_processing()->echo_cancellation()->Enable(false) !=
560 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000561 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200562 "SetEcStatus() failed to disable AEC");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000563 return -1;
564 }
565 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000566 }
Jelena Marusic0d266052015-05-04 14:15:32 +0200567 if (_shared->audio_processing()->echo_control_mobile()->Enable(enable) !=
568 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000569 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200570 "SetEcStatus() failed to set AECM state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000571 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000572 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000573 _isAecMode = false;
574 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000575 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200576 "SetEcStatus() invalid EC mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000577 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000578 }
579
580 return 0;
581#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000582 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200583 "SetEcStatus() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000584 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000585#endif
586}
587
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000588int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000589#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000590 if (!_shared->statistics().Initialized()) {
591 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000592 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000593 }
594
595 if (_isAecMode == true) {
596 mode = kEcAec;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000597 enabled = _shared->audio_processing()->echo_cancellation()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000598 } else {
599 mode = kEcAecm;
Jelena Marusic0d266052015-05-04 14:15:32 +0200600 enabled = _shared->audio_processing()->echo_control_mobile()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000601 }
602
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000603 return 0;
604#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000605 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200606 "GetEcStatus() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000607 return -1;
608#endif
609}
610
611void VoEAudioProcessingImpl::SetDelayOffsetMs(int offset) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000612 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000613 "SetDelayOffsetMs(offset = %d)", offset);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000614 _shared->audio_processing()->set_delay_offset_ms(offset);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000615}
616
617int VoEAudioProcessingImpl::DelayOffsetMs() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000618 return _shared->audio_processing()->delay_offset_ms();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000619}
620
621int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000622 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000623 "SetAECMMode(mode = %d)", mode);
624#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000625 if (!_shared->statistics().Initialized()) {
626 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000627 return -1;
628 }
629
630 EchoControlMobile::RoutingMode aecmMode(
631 EchoControlMobile::kQuietEarpieceOrHeadset);
632
633 switch (mode) {
634 case kAecmQuietEarpieceOrHeadset:
635 aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
636 break;
637 case kAecmEarpiece:
638 aecmMode = EchoControlMobile::kEarpiece;
639 break;
640 case kAecmLoudEarpiece:
641 aecmMode = EchoControlMobile::kLoudEarpiece;
642 break;
643 case kAecmSpeakerphone:
644 aecmMode = EchoControlMobile::kSpeakerphone;
645 break;
646 case kAecmLoudSpeakerphone:
647 aecmMode = EchoControlMobile::kLoudSpeakerphone;
648 break;
649 }
650
Jelena Marusic0d266052015-05-04 14:15:32 +0200651 if (_shared->audio_processing()->echo_control_mobile()->set_routing_mode(
652 aecmMode) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000653 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200654 "SetAECMMode() failed to set AECM routing mode");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000655 return -1;
656 }
Jelena Marusic0d266052015-05-04 14:15:32 +0200657 if (_shared->audio_processing()->echo_control_mobile()->enable_comfort_noise(
658 enableCNG) != 0) {
659 _shared->SetLastError(
660 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000661 "SetAECMMode() failed to set comfort noise state for AECM");
662 return -1;
663 }
664
665 return 0;
666#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000667 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200668 "SetAECMMode() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000669 return -1;
670#endif
671}
672
673int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000674#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000675 if (!_shared->statistics().Initialized()) {
676 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000677 return -1;
678 }
679
680 enabledCNG = false;
681
682 EchoControlMobile::RoutingMode aecmMode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000683 _shared->audio_processing()->echo_control_mobile()->routing_mode();
Jelena Marusic0d266052015-05-04 14:15:32 +0200684 enabledCNG = _shared->audio_processing()
685 ->echo_control_mobile()
686 ->is_comfort_noise_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000687
688 switch (aecmMode) {
689 case EchoControlMobile::kQuietEarpieceOrHeadset:
690 mode = kAecmQuietEarpieceOrHeadset;
691 break;
692 case EchoControlMobile::kEarpiece:
693 mode = kAecmEarpiece;
694 break;
695 case EchoControlMobile::kLoudEarpiece:
696 mode = kAecmLoudEarpiece;
697 break;
698 case EchoControlMobile::kSpeakerphone:
699 mode = kAecmSpeakerphone;
700 break;
701 case EchoControlMobile::kLoudSpeakerphone:
702 mode = kAecmLoudSpeakerphone;
703 break;
704 }
705
706 return 0;
707#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000708 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200709 "GetAECMMode() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000710 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000711#endif
712}
713
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000714int VoEAudioProcessingImpl::EnableHighPassFilter(bool enable) {
715 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
716 "EnableHighPassFilter(%d)", enable);
717 if (_shared->audio_processing()->high_pass_filter()->Enable(enable) !=
718 AudioProcessing::kNoError) {
719 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200720 "HighPassFilter::Enable() failed.");
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000721 return -1;
722 }
723
724 return 0;
725}
726
727bool VoEAudioProcessingImpl::IsHighPassFilterEnabled() {
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000728 return _shared->audio_processing()->high_pass_filter()->is_enabled();
729}
730
Jelena Marusic0d266052015-05-04 14:15:32 +0200731int VoEAudioProcessingImpl::RegisterRxVadObserver(int channel,
732 VoERxVadCallback& observer) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000733 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000734 "RegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000735 if (!_shared->statistics().Initialized()) {
736 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000737 return -1;
738 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000739 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
740 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000741 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000742 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200743 "RegisterRxVadObserver() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000744 return -1;
745 }
746 return channelPtr->RegisterRxVadObserver(observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000747}
748
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000749int VoEAudioProcessingImpl::DeRegisterRxVadObserver(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000750 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000751 "DeRegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000752 if (!_shared->statistics().Initialized()) {
753 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000754 return -1;
755 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000756 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
757 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000758 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000759 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200760 "DeRegisterRxVadObserver() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000761 return -1;
762 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000763
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000764 return channelPtr->DeRegisterRxVadObserver();
niklase@google.com470e71d2011-07-07 08:21:25 +0000765}
766
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000767int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000768 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000769 "VoiceActivityIndicator(channel=%d)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000770 if (!_shared->statistics().Initialized()) {
771 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000772 return -1;
773 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000774
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000775 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
776 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000777 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000778 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200779 "DeRegisterRxVadObserver() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000780 return -1;
781 }
782 int activity(-1);
783 channelPtr->VoiceActivityIndicator(activity);
niklase@google.com470e71d2011-07-07 08:21:25 +0000784
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000785 return activity;
niklase@google.com470e71d2011-07-07 08:21:25 +0000786}
787
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000788int VoEAudioProcessingImpl::SetEcMetricsStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000789 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000790 "SetEcMetricsStatus(enable=%d)", enable);
bjornv@google.com0beae672011-09-28 14:08:19 +0000791#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000792 if (!_shared->statistics().Initialized()) {
793 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000794 return -1;
795 }
796
Jelena Marusic0d266052015-05-04 14:15:32 +0200797 if ((_shared->audio_processing()->echo_cancellation()->enable_metrics(
798 enable) != 0) ||
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000799 (_shared->audio_processing()->echo_cancellation()->enable_delay_logging(
Jelena Marusic0d266052015-05-04 14:15:32 +0200800 enable) != 0)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000801 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200802 "SetEcMetricsStatus() unable to set EC metrics mode");
bjornv@google.com0beae672011-09-28 14:08:19 +0000803 return -1;
804 }
805 return 0;
806#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000807 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200808 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000809 return -1;
810#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000811}
812
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000813int VoEAudioProcessingImpl::GetEcMetricsStatus(bool& enabled) {
bjornv@google.com0beae672011-09-28 14:08:19 +0000814#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000815 if (!_shared->statistics().Initialized()) {
816 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000817 return -1;
818 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000819
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000820 bool echo_mode =
Jelena Marusic0d266052015-05-04 14:15:32 +0200821 _shared->audio_processing()->echo_cancellation()->are_metrics_enabled();
822 bool delay_mode = _shared->audio_processing()
823 ->echo_cancellation()
824 ->is_delay_logging_enabled();
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000825
826 if (echo_mode != delay_mode) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200827 _shared->SetLastError(
828 VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000829 "GetEcMetricsStatus() delay logging and echo mode are not the same");
830 return -1;
831 }
832
833 enabled = echo_mode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000834
bjornv@google.com0beae672011-09-28 14:08:19 +0000835 return 0;
836#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000837 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200838 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000839 return -1;
840#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000841}
842
843int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
844 int& ERLE,
845 int& RERL,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000846 int& A_NLP) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000847#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000848 if (!_shared->statistics().Initialized()) {
849 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000850 return -1;
851 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000852 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200853 _shared->SetLastError(
854 VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000855 "GetEchoMetrics() AudioProcessingModule AEC is not enabled");
856 return -1;
857 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000858
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000859 // Get Echo Metrics from Audio Processing Module.
860 EchoCancellation::Metrics echoMetrics;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000861 if (_shared->audio_processing()->echo_cancellation()->GetMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000862 &echoMetrics)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000863 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000864 "GetEchoMetrics(), AudioProcessingModule metrics error");
865 return -1;
866 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000867
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000868 // Echo quality metrics.
869 ERL = echoMetrics.echo_return_loss.instant;
870 ERLE = echoMetrics.echo_return_loss_enhancement.instant;
871 RERL = echoMetrics.residual_echo_return_loss.instant;
872 A_NLP = echoMetrics.a_nlp.instant;
niklase@google.com470e71d2011-07-07 08:21:25 +0000873
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000874 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000875#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000876 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200877 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000878 return -1;
879#endif
880}
881
882int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median,
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000883 int& delay_std,
884 float& fraction_poor_delays) {
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000885#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000886 if (!_shared->statistics().Initialized()) {
887 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000888 return -1;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000889 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000890 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200891 _shared->SetLastError(
892 VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000893 "GetEcDelayMetrics() AudioProcessingModule AEC is not enabled");
894 return -1;
895 }
896
897 int median = 0;
898 int std = 0;
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000899 float poor_fraction = 0;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000900 // Get delay-logging values from Audio Processing Module.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000901 if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics(
Jelena Marusic0d266052015-05-04 14:15:32 +0200902 &median, &std, &poor_fraction)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000903 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000904 "GetEcDelayMetrics(), AudioProcessingModule delay-logging "
905 "error");
906 return -1;
907 }
908
909 // EC delay-logging metrics
910 delay_median = median;
911 delay_std = std;
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000912 fraction_poor_delays = poor_fraction;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000913
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000914 return 0;
915#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000916 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200917 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000918 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000919#endif
920}
921
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000922int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000923 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000924 "StartDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000925 if (!_shared->statistics().Initialized()) {
926 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000927 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000928 }
929
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000930 return _shared->audio_processing()->StartDebugRecording(fileNameUTF8);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000931}
932
henrikg@webrtc.org863b5362013-12-06 16:05:17 +0000933int VoEAudioProcessingImpl::StartDebugRecording(FILE* file_handle) {
934 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
935 "StartDebugRecording()");
936 if (!_shared->statistics().Initialized()) {
937 _shared->SetLastError(VE_NOT_INITED, kTraceError);
938 return -1;
939 }
940
941 return _shared->audio_processing()->StartDebugRecording(file_handle);
942}
943
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000944int VoEAudioProcessingImpl::StopDebugRecording() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000945 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000946 "StopDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000947 if (!_shared->statistics().Initialized()) {
948 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000949 return -1;
950 }
951
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000952 return _shared->audio_processing()->StopDebugRecording();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000953}
954
955int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000956 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000957 "SetTypingDetectionStatus()");
andrew@webrtc.org0851df82013-06-19 17:03:47 +0000958#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
959 NOT_SUPPORTED(_shared->statistics());
960#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000961 if (!_shared->statistics().Initialized()) {
962 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000963 return -1;
964 }
965
966 // Just use the VAD state to determine if we should enable typing detection
967 // or not
968
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000969 if (_shared->audio_processing()->voice_detection()->Enable(enable)) {
970 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200971 "SetTypingDetectionStatus() failed to set VAD state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000972 return -1;
973 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000974 if (_shared->audio_processing()->voice_detection()->set_likelihood(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000975 VoiceDetection::kVeryLowLikelihood)) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200976 _shared->SetLastError(
977 VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000978 "SetTypingDetectionStatus() failed to set VAD likelihood to low");
979 return -1;
980 }
981
982 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000983#endif
984}
985
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000986int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000987 if (!_shared->statistics().Initialized()) {
988 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000989 return -1;
990 }
991 // Just use the VAD state to determine if we should enable typing
992 // detection or not
niklase@google.com470e71d2011-07-07 08:21:25 +0000993
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000994 enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000995
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000996 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000997}
998
Jelena Marusic0d266052015-05-04 14:15:32 +0200999int VoEAudioProcessingImpl::TimeSinceLastTyping(int& seconds) {
andrew@webrtc.org0851df82013-06-19 17:03:47 +00001000#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
1001 NOT_SUPPORTED(_shared->statistics());
1002#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001003 if (!_shared->statistics().Initialized()) {
1004 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001005 return -1;
1006 }
1007 // Check if typing detection is enabled
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001008 bool enabled = _shared->audio_processing()->voice_detection()->is_enabled();
Jelena Marusic0d266052015-05-04 14:15:32 +02001009 if (enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001010 _shared->transmit_mixer()->TimeSinceLastTyping(seconds);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001011 return 0;
Jelena Marusic0d266052015-05-04 14:15:32 +02001012 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001013 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +02001014 "SetTypingDetectionStatus is not enabled");
1015 return -1;
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001016 }
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001017#endif
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001018}
1019
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001020int VoEAudioProcessingImpl::SetTypingDetectionParameters(int timeWindow,
1021 int costPerTyping,
1022 int reportingThreshold,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001023 int penaltyDecay,
1024 int typeEventDelay) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001025 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001026 "SetTypingDetectionParameters()");
andrew@webrtc.org0851df82013-06-19 17:03:47 +00001027#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
1028 NOT_SUPPORTED(_shared->statistics());
1029#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001030 if (!_shared->statistics().Initialized()) {
1031 _shared->statistics().SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001032 return -1;
1033 }
Jelena Marusic0d266052015-05-04 14:15:32 +02001034 return (_shared->transmit_mixer()->SetTypingDetectionParameters(
1035 timeWindow, costPerTyping, reportingThreshold, penaltyDecay,
1036 typeEventDelay));
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001037#endif
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001038}
1039
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001040void VoEAudioProcessingImpl::EnableStereoChannelSwapping(bool enable) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +00001041 LOG_API1(enable);
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001042 _shared->transmit_mixer()->EnableStereoChannelSwapping(enable);
1043}
1044
1045bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
andrew@webrtc.org50419b02012-11-14 19:07:54 +00001046 LOG_API0();
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001047 return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
1048}
1049
niklase@google.com470e71d2011-07-07 08:21:25 +00001050#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
1051
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001052} // namespace webrtc