blob: 7e082fde20d871b1559520e2df93afe91d96e67e [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/trace.h"
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000016#include "webrtc/voice_engine/channel.h"
17#include "webrtc/voice_engine/include/voe_errors.h"
18#include "webrtc/voice_engine/transmit_mixer.h"
19#include "webrtc/voice_engine/voice_engine_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020
andrew@webrtc.org02d71742012-04-24 19:47:00 +000021// TODO(andrew): move to a common place.
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +000022#define WEBRTC_VOICE_INIT_CHECK() \
23 do { \
24 if (!_shared->statistics().Initialized()) { \
25 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
26 return -1; \
27 } \
28 } while (0)
29
30#define WEBRTC_VOICE_INIT_CHECK_BOOL() \
31 do { \
32 if (!_shared->statistics().Initialized()) { \
33 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
34 return false; \
35 } \
36 } while (0)
37
niklase@google.com470e71d2011-07-07 08:21:25 +000038namespace webrtc {
39
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +000040#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
andrew@webrtc.org80124742012-03-08 17:54:24 +000041static const EcModes kDefaultEcMode = kEcAecm;
42#else
43static const EcModes kDefaultEcMode = kEcAec;
44#endif
45
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000046VoEAudioProcessing* VoEAudioProcessing::GetInterface(VoiceEngine* voiceEngine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000047#ifndef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000048 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000049#else
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000050 if (NULL == voiceEngine) {
51 return NULL;
52 }
tommi@webrtc.org0989fb72013-02-15 15:07:32 +000053 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
tommi@webrtc.orga990e122012-04-26 15:28:22 +000054 s->AddRef();
55 return s;
niklase@google.com470e71d2011-07-07 08:21:25 +000056#endif
57}
58
59#ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
tommi@webrtc.org851becd2012-04-04 14:57:19 +000060VoEAudioProcessingImpl::VoEAudioProcessingImpl(voe::SharedData* shared)
Jelena Marusic0d266052015-05-04 14:15:32 +020061 : _isAecMode(kDefaultEcMode == kEcAec), _shared(shared) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000062 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000063 "VoEAudioProcessingImpl::VoEAudioProcessingImpl() - ctor");
niklase@google.com470e71d2011-07-07 08:21:25 +000064}
65
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000066VoEAudioProcessingImpl::~VoEAudioProcessingImpl() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000067 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000068 "VoEAudioProcessingImpl::~VoEAudioProcessingImpl() - dtor");
niklase@google.com470e71d2011-07-07 08:21:25 +000069}
70
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000071int VoEAudioProcessingImpl::SetNsStatus(bool enable, NsModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000072 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000073 "SetNsStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +000074#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +000075 if (!_shared->statistics().Initialized()) {
76 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000077 return -1;
78 }
niklase@google.com470e71d2011-07-07 08:21:25 +000079
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000080 NoiseSuppression::Level nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000081 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000082 case kNsDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000083 nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000084 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000085 case kNsUnchanged:
tommi@webrtc.org851becd2012-04-04 14:57:19 +000086 nsLevel = _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000087 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000088 case kNsConference:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000089 nsLevel = NoiseSuppression::kHigh;
90 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000091 case kNsLowSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000092 nsLevel = NoiseSuppression::kLow;
93 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000094 case kNsModerateSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000095 nsLevel = NoiseSuppression::kModerate;
96 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000097 case kNsHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000098 nsLevel = NoiseSuppression::kHigh;
99 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000100 case kNsVeryHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000101 nsLevel = NoiseSuppression::kVeryHigh;
102 break;
103 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000104
Jelena Marusic0d266052015-05-04 14:15:32 +0200105 if (_shared->audio_processing()->noise_suppression()->set_level(nsLevel) !=
106 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000107 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200108 "SetNsStatus() failed to set Ns mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000109 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000110 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000111 if (_shared->audio_processing()->noise_suppression()->Enable(enable) != 0) {
112 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200113 "SetNsStatus() failed to set Ns state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000114 return -1;
115 }
116
117 return 0;
118#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000119 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200120 "SetNsStatus() Ns is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000121 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000122#endif
123}
124
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000125int VoEAudioProcessingImpl::GetNsStatus(bool& enabled, NsModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000126#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000127 if (!_shared->statistics().Initialized()) {
128 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000129 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000130 }
131
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000132 enabled = _shared->audio_processing()->noise_suppression()->is_enabled();
133 NoiseSuppression::Level nsLevel =
134 _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000135
136 switch (nsLevel) {
137 case NoiseSuppression::kLow:
138 mode = kNsLowSuppression;
139 break;
140 case NoiseSuppression::kModerate:
141 mode = kNsModerateSuppression;
142 break;
143 case NoiseSuppression::kHigh:
144 mode = kNsHighSuppression;
145 break;
146 case NoiseSuppression::kVeryHigh:
147 mode = kNsVeryHighSuppression;
148 break;
149 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000150 return 0;
151#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000152 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200153 "GetNsStatus() Ns is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000154 return -1;
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000155#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000156}
157
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000158int VoEAudioProcessingImpl::SetAgcStatus(bool enable, AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000159 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000160 "SetAgcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000161#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000162 if (!_shared->statistics().Initialized()) {
163 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000164 return -1;
165 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000166
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000167#if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000168 if (mode == kAgcAdaptiveAnalog) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000169 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200170 "SetAgcStatus() invalid Agc mode for mobile device");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000171 return -1;
172 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000173#endif
174
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000175 GainControl::Mode agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000176 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000177 case kAgcDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000178 agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000179 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000180 case kAgcUnchanged:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000181 agcMode = _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000182 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000183 case kAgcFixedDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000184 agcMode = GainControl::kFixedDigital;
185 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000186 case kAgcAdaptiveAnalog:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000187 agcMode = GainControl::kAdaptiveAnalog;
188 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000189 case kAgcAdaptiveDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000190 agcMode = GainControl::kAdaptiveDigital;
191 break;
192 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000193
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000194 if (_shared->audio_processing()->gain_control()->set_mode(agcMode) != 0) {
195 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200196 "SetAgcStatus() failed to set Agc mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000197 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000198 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000199 if (_shared->audio_processing()->gain_control()->Enable(enable) != 0) {
200 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200201 "SetAgcStatus() failed to set Agc state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000202 return -1;
203 }
204
205 if (agcMode != GainControl::kFixedDigital) {
206 // Set Agc state in the ADM when adaptive Agc mode has been selected.
207 // Note that we also enable the ADM Agc when Adaptive Digital mode is
208 // used since we want to be able to provide the APM with updated mic
209 // levels when the user modifies the mic level manually.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000210 if (_shared->audio_device()->SetAGC(enable) != 0) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200211 _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning,
212 "SetAgcStatus() failed to set Agc mode");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000213 }
214 }
215
216 return 0;
217#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000218 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200219 "SetAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000220 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000221#endif
222}
223
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000224int VoEAudioProcessingImpl::GetAgcStatus(bool& enabled, AgcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000225#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000226 if (!_shared->statistics().Initialized()) {
227 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000228 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000229 }
230
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000231 enabled = _shared->audio_processing()->gain_control()->is_enabled();
sjlee@webrtc.orgb4c441a2013-03-25 11:12:20 +0000232 GainControl::Mode agcMode =
Jelena Marusic0d266052015-05-04 14:15:32 +0200233 _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000234
235 switch (agcMode) {
236 case GainControl::kFixedDigital:
237 mode = kAgcFixedDigital;
238 break;
239 case GainControl::kAdaptiveAnalog:
240 mode = kAgcAdaptiveAnalog;
241 break;
242 case GainControl::kAdaptiveDigital:
243 mode = kAgcAdaptiveDigital;
244 break;
245 }
246
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000247 return 0;
248#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000249 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200250 "GetAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000251 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000252#endif
253}
254
pbos@webrtc.org92135212013-05-14 08:31:39 +0000255int VoEAudioProcessingImpl::SetAgcConfig(AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000256 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000257 "SetAgcConfig()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000258#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000259 if (!_shared->statistics().Initialized()) {
260 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000261 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000262 }
263
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000264 if (_shared->audio_processing()->gain_control()->set_target_level_dbfs(
Jelena Marusic0d266052015-05-04 14:15:32 +0200265 config.targetLeveldBOv) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000266 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200267 "SetAgcConfig() failed to set target peak |level|"
268 " (or envelope) of the Agc");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000269 return -1;
270 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000271 if (_shared->audio_processing()->gain_control()->set_compression_gain_db(
Jelena Marusic0d266052015-05-04 14:15:32 +0200272 config.digitalCompressionGaindB) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000273 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200274 "SetAgcConfig() failed to set the range in |gain| "
275 "the digital compression stage may apply");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000276 return -1;
277 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000278 if (_shared->audio_processing()->gain_control()->enable_limiter(
Jelena Marusic0d266052015-05-04 14:15:32 +0200279 config.limiterEnable) != 0) {
280 _shared->SetLastError(
281 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000282 "SetAgcConfig() failed to set hard limiter to the signal");
283 return -1;
284 }
285
286 return 0;
287#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000288 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200289 "SetAgcConfig() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000290 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000291#endif
292}
293
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000294int VoEAudioProcessingImpl::GetAgcConfig(AgcConfig& config) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000295#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000296 if (!_shared->statistics().Initialized()) {
297 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000298 return -1;
299 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000300
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000301 config.targetLeveldBOv =
Jelena Marusic0d266052015-05-04 14:15:32 +0200302 _shared->audio_processing()->gain_control()->target_level_dbfs();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000303 config.digitalCompressionGaindB =
Jelena Marusic0d266052015-05-04 14:15:32 +0200304 _shared->audio_processing()->gain_control()->compression_gain_db();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000305 config.limiterEnable =
Jelena Marusic0d266052015-05-04 14:15:32 +0200306 _shared->audio_processing()->gain_control()->is_limiter_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000307
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000308 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000309#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000310 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200311 "GetAgcConfig() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000312 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000313#endif
314}
315
316int VoEAudioProcessingImpl::SetRxNsStatus(int channel,
317 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000318 NsModes mode) {
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000319#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000320 if (!_shared->statistics().Initialized()) {
321 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000322 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000323 }
324
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000325 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
326 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000327 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000328 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200329 "SetRxNsStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000330 return -1;
331 }
332 return channelPtr->SetRxNsStatus(enable, mode);
333#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000334 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200335 "SetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000336 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000337#endif
338}
339
340int VoEAudioProcessingImpl::GetRxNsStatus(int channel,
341 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000342 NsModes& mode) {
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000343#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000344 if (!_shared->statistics().Initialized()) {
345 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000347 }
348
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000349 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
350 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000351 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000352 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200353 "GetRxNsStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000354 return -1;
355 }
356 return channelPtr->GetRxNsStatus(enabled, mode);
357#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000358 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200359 "GetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000360 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000361#endif
362}
363
364int VoEAudioProcessingImpl::SetRxAgcStatus(int channel,
365 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000366 AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000367 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
Jelena Marusic0d266052015-05-04 14:15:32 +0200368 "SetRxAgcStatus(channel=%d, enable=%d, mode=%d)", channel,
369 (int)enable, (int)mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000370#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000371 if (!_shared->statistics().Initialized()) {
372 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000373 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000374 }
375
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000376 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
377 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000378 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000379 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200380 "SetRxAgcStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000381 return -1;
382 }
383 return channelPtr->SetRxAgcStatus(enable, mode);
384#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000385 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200386 "SetRxAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000387 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000388#endif
389}
390
391int VoEAudioProcessingImpl::GetRxAgcStatus(int channel,
392 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000393 AgcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000394#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000395 if (!_shared->statistics().Initialized()) {
396 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000397 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000398 }
399
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000400 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
401 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000402 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000403 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200404 "GetRxAgcStatus() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000405 return -1;
406 }
407 return channelPtr->GetRxAgcStatus(enabled, mode);
408#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000409 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200410 "GetRxAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000411 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000412#endif
413}
414
Jelena Marusic0d266052015-05-04 14:15:32 +0200415int VoEAudioProcessingImpl::SetRxAgcConfig(int channel, AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000416 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000417 "SetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000418#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000419 if (!_shared->statistics().Initialized()) {
420 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000421 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000422 }
423
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000424 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
425 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000426 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000427 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200428 "SetRxAgcConfig() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000429 return -1;
430 }
431 return channelPtr->SetRxAgcConfig(config);
432#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000433 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200434 "SetRxAgcConfig() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000435 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000436#endif
437}
438
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000439int VoEAudioProcessingImpl::GetRxAgcConfig(int channel, AgcConfig& config) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000440#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000441 if (!_shared->statistics().Initialized()) {
442 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000443 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000444 }
445
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000446 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
447 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000448 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000449 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200450 "GetRxAgcConfig() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000451 return -1;
452 }
453 return channelPtr->GetRxAgcConfig(config);
454#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000455 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200456 "GetRxAgcConfig() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000457 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000458#endif
459}
460
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000461bool VoEAudioProcessing::DriftCompensationSupported() {
462#if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
463 return true;
464#else
465 return false;
466#endif
467}
468
469int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000470 WEBRTC_VOICE_INIT_CHECK();
471
472 if (!DriftCompensationSupported()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200473 _shared->SetLastError(
474 VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000475 "Drift compensation is not supported on this platform.");
476 return -1;
477 }
478
479 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
480 if (aec->enable_drift_compensation(enable) != 0) {
481 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200482 "aec->enable_drift_compensation() failed");
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000483 return -1;
484 }
485 return 0;
486}
487
488bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000489 WEBRTC_VOICE_INIT_CHECK_BOOL();
490
491 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
492 return aec->is_drift_compensation_enabled();
493}
494
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000495int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000496 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000497 "SetEcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000498#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000499 if (!_shared->statistics().Initialized()) {
500 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000501 return -1;
502 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000503
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000504 // AEC mode
Jelena Marusic0d266052015-05-04 14:15:32 +0200505 if ((mode == kEcDefault) || (mode == kEcConference) || (mode == kEcAec) ||
506 ((mode == kEcUnchanged) && (_isAecMode == true))) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000507 if (enable) {
508 // Disable the AECM before enable the AEC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000509 if (_shared->audio_processing()->echo_control_mobile()->is_enabled()) {
510 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200511 "SetEcStatus() disable AECM before enabling AEC");
512 if (_shared->audio_processing()->echo_control_mobile()->Enable(false) !=
513 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000514 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200515 "SetEcStatus() failed to disable AECM");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000516 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000517 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000518 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000519 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000520 if (_shared->audio_processing()->echo_cancellation()->Enable(enable) != 0) {
521 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200522 "SetEcStatus() failed to set AEC state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000523 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000524 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000525 if (mode == kEcConference) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200526 if (_shared->audio_processing()
527 ->echo_cancellation()
528 ->set_suppression_level(EchoCancellation::kHighSuppression) !=
529 0) {
530 _shared->SetLastError(
531 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000532 "SetEcStatus() failed to set aggressiveness to high");
niklase@google.com470e71d2011-07-07 08:21:25 +0000533 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000534 }
535 } else {
Jelena Marusic0d266052015-05-04 14:15:32 +0200536 if (_shared->audio_processing()
537 ->echo_cancellation()
538 ->set_suppression_level(EchoCancellation::kModerateSuppression) !=
539 0) {
540 _shared->SetLastError(
541 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000542 "SetEcStatus() failed to set aggressiveness to moderate");
niklase@google.com470e71d2011-07-07 08:21:25 +0000543 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000544 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000545 }
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000546
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000547 _isAecMode = true;
548 } else if ((mode == kEcAecm) ||
Jelena Marusic0d266052015-05-04 14:15:32 +0200549 ((mode == kEcUnchanged) && (_isAecMode == false))) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000550 if (enable) {
551 // Disable the AEC before enable the AECM
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000552 if (_shared->audio_processing()->echo_cancellation()->is_enabled()) {
553 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200554 "SetEcStatus() disable AEC before enabling AECM");
555 if (_shared->audio_processing()->echo_cancellation()->Enable(false) !=
556 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000557 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200558 "SetEcStatus() failed to disable AEC");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000559 return -1;
560 }
561 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000562 }
Jelena Marusic0d266052015-05-04 14:15:32 +0200563 if (_shared->audio_processing()->echo_control_mobile()->Enable(enable) !=
564 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000565 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200566 "SetEcStatus() failed to set AECM state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000567 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000568 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000569 _isAecMode = false;
570 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000571 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200572 "SetEcStatus() invalid EC mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000573 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000574 }
575
576 return 0;
577#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000578 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200579 "SetEcStatus() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000580 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000581#endif
582}
583
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000584int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000585#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000586 if (!_shared->statistics().Initialized()) {
587 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000588 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000589 }
590
591 if (_isAecMode == true) {
592 mode = kEcAec;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000593 enabled = _shared->audio_processing()->echo_cancellation()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000594 } else {
595 mode = kEcAecm;
Jelena Marusic0d266052015-05-04 14:15:32 +0200596 enabled = _shared->audio_processing()->echo_control_mobile()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000597 }
598
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000599 return 0;
600#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000601 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200602 "GetEcStatus() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000603 return -1;
604#endif
605}
606
607void VoEAudioProcessingImpl::SetDelayOffsetMs(int offset) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000608 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000609 "SetDelayOffsetMs(offset = %d)", offset);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000610 _shared->audio_processing()->set_delay_offset_ms(offset);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000611}
612
613int VoEAudioProcessingImpl::DelayOffsetMs() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000614 return _shared->audio_processing()->delay_offset_ms();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000615}
616
617int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000618 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000619 "SetAECMMode(mode = %d)", mode);
620#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000621 if (!_shared->statistics().Initialized()) {
622 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000623 return -1;
624 }
625
626 EchoControlMobile::RoutingMode aecmMode(
627 EchoControlMobile::kQuietEarpieceOrHeadset);
628
629 switch (mode) {
630 case kAecmQuietEarpieceOrHeadset:
631 aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
632 break;
633 case kAecmEarpiece:
634 aecmMode = EchoControlMobile::kEarpiece;
635 break;
636 case kAecmLoudEarpiece:
637 aecmMode = EchoControlMobile::kLoudEarpiece;
638 break;
639 case kAecmSpeakerphone:
640 aecmMode = EchoControlMobile::kSpeakerphone;
641 break;
642 case kAecmLoudSpeakerphone:
643 aecmMode = EchoControlMobile::kLoudSpeakerphone;
644 break;
645 }
646
Jelena Marusic0d266052015-05-04 14:15:32 +0200647 if (_shared->audio_processing()->echo_control_mobile()->set_routing_mode(
648 aecmMode) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000649 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200650 "SetAECMMode() failed to set AECM routing mode");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000651 return -1;
652 }
Jelena Marusic0d266052015-05-04 14:15:32 +0200653 if (_shared->audio_processing()->echo_control_mobile()->enable_comfort_noise(
654 enableCNG) != 0) {
655 _shared->SetLastError(
656 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000657 "SetAECMMode() failed to set comfort noise state for AECM");
658 return -1;
659 }
660
661 return 0;
662#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000663 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200664 "SetAECMMode() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000665 return -1;
666#endif
667}
668
669int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000670#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000671 if (!_shared->statistics().Initialized()) {
672 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000673 return -1;
674 }
675
676 enabledCNG = false;
677
678 EchoControlMobile::RoutingMode aecmMode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000679 _shared->audio_processing()->echo_control_mobile()->routing_mode();
Jelena Marusic0d266052015-05-04 14:15:32 +0200680 enabledCNG = _shared->audio_processing()
681 ->echo_control_mobile()
682 ->is_comfort_noise_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000683
684 switch (aecmMode) {
685 case EchoControlMobile::kQuietEarpieceOrHeadset:
686 mode = kAecmQuietEarpieceOrHeadset;
687 break;
688 case EchoControlMobile::kEarpiece:
689 mode = kAecmEarpiece;
690 break;
691 case EchoControlMobile::kLoudEarpiece:
692 mode = kAecmLoudEarpiece;
693 break;
694 case EchoControlMobile::kSpeakerphone:
695 mode = kAecmSpeakerphone;
696 break;
697 case EchoControlMobile::kLoudSpeakerphone:
698 mode = kAecmLoudSpeakerphone;
699 break;
700 }
701
702 return 0;
703#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000704 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200705 "GetAECMMode() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000706 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000707#endif
708}
709
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000710int VoEAudioProcessingImpl::EnableHighPassFilter(bool enable) {
711 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
712 "EnableHighPassFilter(%d)", enable);
713 if (_shared->audio_processing()->high_pass_filter()->Enable(enable) !=
714 AudioProcessing::kNoError) {
715 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200716 "HighPassFilter::Enable() failed.");
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000717 return -1;
718 }
719
720 return 0;
721}
722
723bool VoEAudioProcessingImpl::IsHighPassFilterEnabled() {
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000724 return _shared->audio_processing()->high_pass_filter()->is_enabled();
725}
726
Jelena Marusic0d266052015-05-04 14:15:32 +0200727int VoEAudioProcessingImpl::RegisterRxVadObserver(int channel,
728 VoERxVadCallback& observer) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000729 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000730 "RegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000731 if (!_shared->statistics().Initialized()) {
732 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000733 return -1;
734 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000735 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
736 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000737 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000738 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200739 "RegisterRxVadObserver() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000740 return -1;
741 }
742 return channelPtr->RegisterRxVadObserver(observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000743}
744
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000745int VoEAudioProcessingImpl::DeRegisterRxVadObserver(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000746 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000747 "DeRegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000748 if (!_shared->statistics().Initialized()) {
749 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000750 return -1;
751 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000752 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
753 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000754 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000755 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200756 "DeRegisterRxVadObserver() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000757 return -1;
758 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000759
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000760 return channelPtr->DeRegisterRxVadObserver();
niklase@google.com470e71d2011-07-07 08:21:25 +0000761}
762
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000763int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000764 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000765 "VoiceActivityIndicator(channel=%d)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000766 if (!_shared->statistics().Initialized()) {
767 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000768 return -1;
769 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000770
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000771 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
772 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000773 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000774 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200775 "DeRegisterRxVadObserver() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000776 return -1;
777 }
778 int activity(-1);
779 channelPtr->VoiceActivityIndicator(activity);
niklase@google.com470e71d2011-07-07 08:21:25 +0000780
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000781 return activity;
niklase@google.com470e71d2011-07-07 08:21:25 +0000782}
783
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000784int VoEAudioProcessingImpl::SetEcMetricsStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000785 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000786 "SetEcMetricsStatus(enable=%d)", enable);
bjornv@google.com0beae672011-09-28 14:08:19 +0000787#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000788 if (!_shared->statistics().Initialized()) {
789 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000790 return -1;
791 }
792
Jelena Marusic0d266052015-05-04 14:15:32 +0200793 if ((_shared->audio_processing()->echo_cancellation()->enable_metrics(
794 enable) != 0) ||
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000795 (_shared->audio_processing()->echo_cancellation()->enable_delay_logging(
Jelena Marusic0d266052015-05-04 14:15:32 +0200796 enable) != 0)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000797 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200798 "SetEcMetricsStatus() unable to set EC metrics mode");
bjornv@google.com0beae672011-09-28 14:08:19 +0000799 return -1;
800 }
801 return 0;
802#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000803 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200804 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000805 return -1;
806#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000807}
808
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000809int VoEAudioProcessingImpl::GetEcMetricsStatus(bool& enabled) {
bjornv@google.com0beae672011-09-28 14:08:19 +0000810#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000811 if (!_shared->statistics().Initialized()) {
812 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000813 return -1;
814 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000815
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000816 bool echo_mode =
Jelena Marusic0d266052015-05-04 14:15:32 +0200817 _shared->audio_processing()->echo_cancellation()->are_metrics_enabled();
818 bool delay_mode = _shared->audio_processing()
819 ->echo_cancellation()
820 ->is_delay_logging_enabled();
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000821
822 if (echo_mode != delay_mode) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200823 _shared->SetLastError(
824 VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000825 "GetEcMetricsStatus() delay logging and echo mode are not the same");
826 return -1;
827 }
828
829 enabled = echo_mode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000830
bjornv@google.com0beae672011-09-28 14:08:19 +0000831 return 0;
832#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000833 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200834 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000835 return -1;
836#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000837}
838
839int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
840 int& ERLE,
841 int& RERL,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000842 int& A_NLP) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000843#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000844 if (!_shared->statistics().Initialized()) {
845 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000846 return -1;
847 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000848 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200849 _shared->SetLastError(
850 VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000851 "GetEchoMetrics() AudioProcessingModule AEC is not enabled");
852 return -1;
853 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000854
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000855 // Get Echo Metrics from Audio Processing Module.
856 EchoCancellation::Metrics echoMetrics;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000857 if (_shared->audio_processing()->echo_cancellation()->GetMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000858 &echoMetrics)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000859 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000860 "GetEchoMetrics(), AudioProcessingModule metrics error");
861 return -1;
862 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000863
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000864 // Echo quality metrics.
865 ERL = echoMetrics.echo_return_loss.instant;
866 ERLE = echoMetrics.echo_return_loss_enhancement.instant;
867 RERL = echoMetrics.residual_echo_return_loss.instant;
868 A_NLP = echoMetrics.a_nlp.instant;
niklase@google.com470e71d2011-07-07 08:21:25 +0000869
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000870 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000871#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000872 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200873 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000874 return -1;
875#endif
876}
877
878int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median,
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000879 int& delay_std,
880 float& fraction_poor_delays) {
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000881#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000882 if (!_shared->statistics().Initialized()) {
883 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000884 return -1;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000885 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000886 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200887 _shared->SetLastError(
888 VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000889 "GetEcDelayMetrics() AudioProcessingModule AEC is not enabled");
890 return -1;
891 }
892
893 int median = 0;
894 int std = 0;
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000895 float poor_fraction = 0;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000896 // Get delay-logging values from Audio Processing Module.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000897 if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics(
Jelena Marusic0d266052015-05-04 14:15:32 +0200898 &median, &std, &poor_fraction)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000899 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000900 "GetEcDelayMetrics(), AudioProcessingModule delay-logging "
901 "error");
902 return -1;
903 }
904
905 // EC delay-logging metrics
906 delay_median = median;
907 delay_std = std;
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000908 fraction_poor_delays = poor_fraction;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000909
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000910 return 0;
911#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000912 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200913 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000914 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000915#endif
916}
917
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000918int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000919 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000920 "StartDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000921 if (!_shared->statistics().Initialized()) {
922 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000923 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000924 }
925
ivocd66b44d2016-01-15 03:06:36 -0800926 return _shared->audio_processing()->StartDebugRecording(fileNameUTF8, -1);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000927}
928
henrikg@webrtc.org863b5362013-12-06 16:05:17 +0000929int VoEAudioProcessingImpl::StartDebugRecording(FILE* file_handle) {
930 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
931 "StartDebugRecording()");
932 if (!_shared->statistics().Initialized()) {
933 _shared->SetLastError(VE_NOT_INITED, kTraceError);
934 return -1;
935 }
936
ivocd66b44d2016-01-15 03:06:36 -0800937 return _shared->audio_processing()->StartDebugRecording(file_handle, -1);
henrikg@webrtc.org863b5362013-12-06 16:05:17 +0000938}
939
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000940int VoEAudioProcessingImpl::StopDebugRecording() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000941 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000942 "StopDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000943 if (!_shared->statistics().Initialized()) {
944 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000945 return -1;
946 }
947
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000948 return _shared->audio_processing()->StopDebugRecording();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000949}
950
951int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000952 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000953 "SetTypingDetectionStatus()");
andrew@webrtc.org0851df82013-06-19 17:03:47 +0000954#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
955 NOT_SUPPORTED(_shared->statistics());
956#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000957 if (!_shared->statistics().Initialized()) {
958 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000959 return -1;
960 }
961
962 // Just use the VAD state to determine if we should enable typing detection
963 // or not
964
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000965 if (_shared->audio_processing()->voice_detection()->Enable(enable)) {
966 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200967 "SetTypingDetectionStatus() failed to set VAD state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000968 return -1;
969 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000970 if (_shared->audio_processing()->voice_detection()->set_likelihood(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000971 VoiceDetection::kVeryLowLikelihood)) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200972 _shared->SetLastError(
973 VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000974 "SetTypingDetectionStatus() failed to set VAD likelihood to low");
975 return -1;
976 }
977
978 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000979#endif
980}
981
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000982int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000983 if (!_shared->statistics().Initialized()) {
984 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000985 return -1;
986 }
987 // Just use the VAD state to determine if we should enable typing
988 // detection or not
niklase@google.com470e71d2011-07-07 08:21:25 +0000989
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000990 enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000991
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000992 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000993}
994
Jelena Marusic0d266052015-05-04 14:15:32 +0200995int VoEAudioProcessingImpl::TimeSinceLastTyping(int& seconds) {
andrew@webrtc.org0851df82013-06-19 17:03:47 +0000996#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
997 NOT_SUPPORTED(_shared->statistics());
998#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000999 if (!_shared->statistics().Initialized()) {
1000 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001001 return -1;
1002 }
1003 // Check if typing detection is enabled
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001004 bool enabled = _shared->audio_processing()->voice_detection()->is_enabled();
Jelena Marusic0d266052015-05-04 14:15:32 +02001005 if (enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001006 _shared->transmit_mixer()->TimeSinceLastTyping(seconds);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001007 return 0;
Jelena Marusic0d266052015-05-04 14:15:32 +02001008 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001009 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +02001010 "SetTypingDetectionStatus is not enabled");
1011 return -1;
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001012 }
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001013#endif
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001014}
1015
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001016int VoEAudioProcessingImpl::SetTypingDetectionParameters(int timeWindow,
1017 int costPerTyping,
1018 int reportingThreshold,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001019 int penaltyDecay,
1020 int typeEventDelay) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001021 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001022 "SetTypingDetectionParameters()");
andrew@webrtc.org0851df82013-06-19 17:03:47 +00001023#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
1024 NOT_SUPPORTED(_shared->statistics());
1025#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001026 if (!_shared->statistics().Initialized()) {
1027 _shared->statistics().SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001028 return -1;
1029 }
Jelena Marusic0d266052015-05-04 14:15:32 +02001030 return (_shared->transmit_mixer()->SetTypingDetectionParameters(
1031 timeWindow, costPerTyping, reportingThreshold, penaltyDecay,
1032 typeEventDelay));
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001033#endif
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001034}
1035
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001036void VoEAudioProcessingImpl::EnableStereoChannelSwapping(bool enable) {
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001037 _shared->transmit_mixer()->EnableStereoChannelSwapping(enable);
1038}
1039
1040bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001041 return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
1042}
1043
niklase@google.com470e71d2011-07-07 08:21:25 +00001044#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
1045
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001046} // namespace webrtc