blob: dd1195c1d556e25d41b5dc13da19c4c64a6feb7c [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
11#include "voe_audio_processing_impl.h"
12
13#include "audio_processing.h"
14#include "channel.h"
15#include "critical_section_wrapper.h"
andrew@webrtc.org50419b02012-11-14 19:07:54 +000016#include "logging.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000017#include "trace.h"
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +000018#include "transmit_mixer.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000019#include "voe_errors.h"
20#include "voice_engine_impl.h"
21
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)
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +000062 : _isAecMode(kDefaultEcMode == kEcAec),
63 _shared(shared) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000064 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000065 "VoEAudioProcessingImpl::VoEAudioProcessingImpl() - ctor");
niklase@google.com470e71d2011-07-07 08:21:25 +000066}
67
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000068VoEAudioProcessingImpl::~VoEAudioProcessingImpl() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000069 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000070 "VoEAudioProcessingImpl::~VoEAudioProcessingImpl() - dtor");
niklase@google.com470e71d2011-07-07 08:21:25 +000071}
72
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000073int VoEAudioProcessingImpl::SetNsStatus(bool enable, NsModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000074 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000075 "SetNsStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +000076#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +000077 if (!_shared->statistics().Initialized()) {
78 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000079 return -1;
80 }
niklase@google.com470e71d2011-07-07 08:21:25 +000081
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000082 NoiseSuppression::Level nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000083 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000084 case kNsDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000085 nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000086 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000087 case kNsUnchanged:
tommi@webrtc.org851becd2012-04-04 14:57:19 +000088 nsLevel = _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000089 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000090 case kNsConference:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000091 nsLevel = NoiseSuppression::kHigh;
92 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000093 case kNsLowSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000094 nsLevel = NoiseSuppression::kLow;
95 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000096 case kNsModerateSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000097 nsLevel = NoiseSuppression::kModerate;
98 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000099 case kNsHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000100 nsLevel = NoiseSuppression::kHigh;
101 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000102 case kNsVeryHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000103 nsLevel = NoiseSuppression::kVeryHigh;
104 break;
105 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000106
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000107 if (_shared->audio_processing()->noise_suppression()->
108 set_level(nsLevel) != 0) {
109 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000110 "SetNsStatus() failed to set Ns mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000111 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000112 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000113 if (_shared->audio_processing()->noise_suppression()->Enable(enable) != 0) {
114 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000115 "SetNsStatus() failed to set Ns state");
116 return -1;
117 }
118
119 return 0;
120#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000121 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000122 "SetNsStatus() Ns is not supported");
123 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000124#endif
125}
126
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000127int VoEAudioProcessingImpl::GetNsStatus(bool& enabled, NsModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000128 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000129 "GetNsStatus(enabled=?, mode=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000130#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000131 if (!_shared->statistics().Initialized()) {
132 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000133 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000134 }
135
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000136 enabled = _shared->audio_processing()->noise_suppression()->is_enabled();
137 NoiseSuppression::Level nsLevel =
138 _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000139
140 switch (nsLevel) {
141 case NoiseSuppression::kLow:
142 mode = kNsLowSuppression;
143 break;
144 case NoiseSuppression::kModerate:
145 mode = kNsModerateSuppression;
146 break;
147 case NoiseSuppression::kHigh:
148 mode = kNsHighSuppression;
149 break;
150 case NoiseSuppression::kVeryHigh:
151 mode = kNsVeryHighSuppression;
152 break;
153 }
154
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000155 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000156 "GetNsStatus() => enabled=% d, mode=%d", enabled, mode);
157 return 0;
158#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000159 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000160 "GetNsStatus() Ns is not supported");
161 return -1;
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000162#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000163}
164
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000165int VoEAudioProcessingImpl::SetAgcStatus(bool enable, AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000166 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000167 "SetAgcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000168#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000169 if (!_shared->statistics().Initialized()) {
170 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000171 return -1;
172 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000173
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000174#if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000175 if (mode == kAgcAdaptiveAnalog) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000176 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000177 "SetAgcStatus() invalid Agc mode for mobile device");
178 return -1;
179 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000180#endif
181
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000182 GainControl::Mode agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000183 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000184 case kAgcDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000185 agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000186 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000187 case kAgcUnchanged:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000188 agcMode = _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000189 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000190 case kAgcFixedDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000191 agcMode = GainControl::kFixedDigital;
192 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000193 case kAgcAdaptiveAnalog:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000194 agcMode = GainControl::kAdaptiveAnalog;
195 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000196 case kAgcAdaptiveDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000197 agcMode = GainControl::kAdaptiveDigital;
198 break;
199 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000200
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000201 if (_shared->audio_processing()->gain_control()->set_mode(agcMode) != 0) {
202 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000203 "SetAgcStatus() failed to set Agc mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000204 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000205 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000206 if (_shared->audio_processing()->gain_control()->Enable(enable) != 0) {
207 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000208 "SetAgcStatus() failed to set Agc state");
209 return -1;
210 }
211
212 if (agcMode != GainControl::kFixedDigital) {
213 // Set Agc state in the ADM when adaptive Agc mode has been selected.
214 // Note that we also enable the ADM Agc when Adaptive Digital mode is
215 // used since we want to be able to provide the APM with updated mic
216 // levels when the user modifies the mic level manually.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000217 if (_shared->audio_device()->SetAGC(enable) != 0) {
218 _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000219 kTraceWarning, "SetAgcStatus() failed to set Agc mode");
220 }
221 }
222
223 return 0;
224#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000225 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000226 "SetAgcStatus() Agc is not supported");
227 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000228#endif
229}
230
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000231int VoEAudioProcessingImpl::GetAgcStatus(bool& enabled, AgcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000232 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000233 "GetAgcStatus(enabled=?, mode=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000234#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000235 if (!_shared->statistics().Initialized()) {
236 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000237 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000238 }
239
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000240 enabled = _shared->audio_processing()->gain_control()->is_enabled();
241 GainControl::Mode agcMode = _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000242
243 switch (agcMode) {
244 case GainControl::kFixedDigital:
245 mode = kAgcFixedDigital;
246 break;
247 case GainControl::kAdaptiveAnalog:
248 mode = kAgcAdaptiveAnalog;
249 break;
250 case GainControl::kAdaptiveDigital:
251 mode = kAgcAdaptiveDigital;
252 break;
253 }
254
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000255 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000256 "GetAgcStatus() => enabled=%d, mode=%d", enabled, mode);
257 return 0;
258#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000259 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000260 "GetAgcStatus() Agc is not supported");
261 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000262#endif
263}
264
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000265int VoEAudioProcessingImpl::SetAgcConfig(const AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000266 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000267 "SetAgcConfig()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000268#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000269 if (!_shared->statistics().Initialized()) {
270 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000271 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000272 }
273
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000274 if (_shared->audio_processing()->gain_control()->set_target_level_dbfs(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000275 config.targetLeveldBOv) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000276 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000277 "SetAgcConfig() failed to set target peak |level|"
278 " (or envelope) of the Agc");
279 return -1;
280 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000281 if (_shared->audio_processing()->gain_control()->set_compression_gain_db(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000282 config.digitalCompressionGaindB) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000283 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000284 "SetAgcConfig() failed to set the range in |gain| "
285 "the digital compression stage may apply");
286 return -1;
287 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000288 if (_shared->audio_processing()->gain_control()->enable_limiter(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000289 config.limiterEnable) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000290 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000291 "SetAgcConfig() failed to set hard limiter to the signal");
292 return -1;
293 }
294
295 return 0;
296#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000297 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000298 "SetAgcConfig() EC is not supported");
299 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000300#endif
301}
302
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000303int VoEAudioProcessingImpl::GetAgcConfig(AgcConfig& config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000304 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000305 "GetAgcConfig(config=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000306#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000307 if (!_shared->statistics().Initialized()) {
308 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000309 return -1;
310 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000311
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000312 config.targetLeveldBOv =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000313 _shared->audio_processing()->gain_control()->target_level_dbfs();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000314 config.digitalCompressionGaindB =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000315 _shared->audio_processing()->gain_control()->compression_gain_db();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000316 config.limiterEnable =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000317 _shared->audio_processing()->gain_control()->is_limiter_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000318
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000319 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000320 "GetAgcConfig() => targetLeveldBOv=%u, "
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000321 "digitalCompressionGaindB=%u, limiterEnable=%d",
322 config.targetLeveldBOv,
323 config.digitalCompressionGaindB,
324 config.limiterEnable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000325
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000326 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000327#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000328 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000329 "GetAgcConfig() EC is not supported");
330 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000331#endif
332}
333
334int VoEAudioProcessingImpl::SetRxNsStatus(int channel,
335 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000336 NsModes mode) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000337 LOG_API3(channel, enable, mode);
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000338#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000339 if (!_shared->statistics().Initialized()) {
340 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000341 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000342 }
343
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000344 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000345 voe::Channel* channelPtr = sc.ChannelPtr();
346 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000347 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000348 "SetRxNsStatus() failed to locate channel");
349 return -1;
350 }
351 return channelPtr->SetRxNsStatus(enable, mode);
352#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000353 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000354 "SetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000355 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000356#endif
357}
358
359int VoEAudioProcessingImpl::GetRxNsStatus(int channel,
360 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000361 NsModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000362 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000363 "GetRxNsStatus(channel=%d, enable=?, mode=?)", channel);
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000364#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000365 if (!_shared->statistics().Initialized()) {
366 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000367 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000368 }
369
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000370 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000371 voe::Channel* channelPtr = sc.ChannelPtr();
372 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000373 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000374 "GetRxNsStatus() failed to locate channel");
375 return -1;
376 }
377 return channelPtr->GetRxNsStatus(enabled, mode);
378#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000379 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000380 "GetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000381 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000382#endif
383}
384
385int VoEAudioProcessingImpl::SetRxAgcStatus(int channel,
386 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000387 AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000388 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000389 "SetRxAgcStatus(channel=%d, enable=%d, mode=%d)",
390 channel, (int)enable, (int)mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000391#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000392 if (!_shared->statistics().Initialized()) {
393 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000394 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000395 }
396
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000397 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000398 voe::Channel* channelPtr = sc.ChannelPtr();
399 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000400 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000401 "SetRxAgcStatus() failed to locate channel");
402 return -1;
403 }
404 return channelPtr->SetRxAgcStatus(enable, mode);
405#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000406 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000407 "SetRxAgcStatus() Agc is not supported");
408 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000409#endif
410}
411
412int VoEAudioProcessingImpl::GetRxAgcStatus(int channel,
413 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000414 AgcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000415 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000416 "GetRxAgcStatus(channel=%d, enable=?, mode=?)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000417#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000418 if (!_shared->statistics().Initialized()) {
419 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000420 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000421 }
422
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000423 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000424 voe::Channel* channelPtr = sc.ChannelPtr();
425 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000426 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000427 "GetRxAgcStatus() failed to locate channel");
428 return -1;
429 }
430 return channelPtr->GetRxAgcStatus(enabled, mode);
431#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000432 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000433 "GetRxAgcStatus() Agc is not supported");
434 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000435#endif
436}
437
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000438int VoEAudioProcessingImpl::SetRxAgcConfig(int channel,
439 const AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000440 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000441 "SetRxAgcConfig(channel=%d)", channel);
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
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000448 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000449 voe::Channel* channelPtr = sc.ChannelPtr();
450 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000451 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000452 "SetRxAgcConfig() failed to locate channel");
453 return -1;
454 }
455 return channelPtr->SetRxAgcConfig(config);
456#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000457 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000458 "SetRxAgcConfig() Agc is not supported");
459 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000460#endif
461}
462
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000463int VoEAudioProcessingImpl::GetRxAgcConfig(int channel, AgcConfig& config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000464 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000465 "GetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000466#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000467 if (!_shared->statistics().Initialized()) {
468 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000469 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000470 }
471
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000472 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000473 voe::Channel* channelPtr = sc.ChannelPtr();
474 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000475 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000476 "GetRxAgcConfig() failed to locate channel");
477 return -1;
478 }
479 return channelPtr->GetRxAgcConfig(config);
480#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000481 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000482 "GetRxAgcConfig() Agc is not supported");
483 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000484#endif
485}
486
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000487bool VoEAudioProcessing::DriftCompensationSupported() {
488#if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
489 return true;
490#else
491 return false;
492#endif
493}
494
495int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000496 LOG_API1(enable);
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000497 WEBRTC_VOICE_INIT_CHECK();
498
499 if (!DriftCompensationSupported()) {
500 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
501 "Drift compensation is not supported on this platform.");
502 return -1;
503 }
504
505 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
506 if (aec->enable_drift_compensation(enable) != 0) {
507 _shared->SetLastError(VE_APM_ERROR, kTraceError,
508 "aec->enable_drift_compensation() failed");
509 return -1;
510 }
511 return 0;
512}
513
514bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000515 LOG_API0();
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000516 WEBRTC_VOICE_INIT_CHECK_BOOL();
517
518 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
519 return aec->is_drift_compensation_enabled();
520}
521
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000522int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000523 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000524 "SetEcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000525#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000526 if (!_shared->statistics().Initialized()) {
527 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000528 return -1;
529 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000530
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000531 // AEC mode
532 if ((mode == kEcDefault) ||
533 (mode == kEcConference) ||
534 (mode == kEcAec) ||
535 ((mode == kEcUnchanged) &&
536 (_isAecMode == true))) {
537 if (enable) {
538 // Disable the AECM before enable the AEC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000539 if (_shared->audio_processing()->echo_control_mobile()->is_enabled()) {
540 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000541 "SetEcStatus() disable AECM before enabling AEC");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000542 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000543 Enable(false) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000544 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000545 "SetEcStatus() failed to disable AECM");
546 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000547 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000548 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000549 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000550 if (_shared->audio_processing()->echo_cancellation()->Enable(enable) != 0) {
551 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000552 "SetEcStatus() failed to set AEC state");
553 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000554 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000555 if (mode == kEcConference) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000556 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000557 set_suppression_level(EchoCancellation::kHighSuppression) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000558 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000559 "SetEcStatus() failed to set aggressiveness to high");
niklase@google.com470e71d2011-07-07 08:21:25 +0000560 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000561 }
562 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000563 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000564 set_suppression_level(
565 EchoCancellation::kModerateSuppression) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000566 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000567 "SetEcStatus() failed to set aggressiveness to moderate");
niklase@google.com470e71d2011-07-07 08:21:25 +0000568 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000569 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000570 }
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000571
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000572 _isAecMode = true;
573 } else if ((mode == kEcAecm) ||
574 ((mode == kEcUnchanged) &&
575 (_isAecMode == false))) {
576 if (enable) {
577 // Disable the AEC before enable the AECM
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000578 if (_shared->audio_processing()->echo_cancellation()->is_enabled()) {
579 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000580 "SetEcStatus() disable AEC before enabling AECM");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000581 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000582 Enable(false) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000583 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000584 "SetEcStatus() failed to disable AEC");
585 return -1;
586 }
587 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000588 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000589 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000590 Enable(enable) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000591 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000592 "SetEcStatus() failed to set AECM state");
593 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000594 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000595 _isAecMode = false;
596 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000597 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000598 "SetEcStatus() invalid EC mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000599 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000600 }
601
602 return 0;
603#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000604 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000605 "SetEcStatus() EC is not supported");
606 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000607#endif
608}
609
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000610int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000611 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000612 "GetEcStatus()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000613#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000614 if (!_shared->statistics().Initialized()) {
615 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000616 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000617 }
618
619 if (_isAecMode == true) {
620 mode = kEcAec;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000621 enabled = _shared->audio_processing()->echo_cancellation()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000622 } else {
623 mode = kEcAecm;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000624 enabled = _shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000625 is_enabled();
626 }
627
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000628 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000629 "GetEcStatus() => enabled=%i, mode=%i",
630 enabled, (int)mode);
631 return 0;
632#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000633 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000634 "GetEcStatus() EC is not supported");
635 return -1;
636#endif
637}
638
639void VoEAudioProcessingImpl::SetDelayOffsetMs(int offset) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000640 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000641 "SetDelayOffsetMs(offset = %d)", offset);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000642 _shared->audio_processing()->set_delay_offset_ms(offset);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000643}
644
645int VoEAudioProcessingImpl::DelayOffsetMs() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000646 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000647 "DelayOffsetMs()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000648 return _shared->audio_processing()->delay_offset_ms();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000649}
650
651int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000652 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000653 "SetAECMMode(mode = %d)", mode);
654#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000655 if (!_shared->statistics().Initialized()) {
656 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000657 return -1;
658 }
659
660 EchoControlMobile::RoutingMode aecmMode(
661 EchoControlMobile::kQuietEarpieceOrHeadset);
662
663 switch (mode) {
664 case kAecmQuietEarpieceOrHeadset:
665 aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
666 break;
667 case kAecmEarpiece:
668 aecmMode = EchoControlMobile::kEarpiece;
669 break;
670 case kAecmLoudEarpiece:
671 aecmMode = EchoControlMobile::kLoudEarpiece;
672 break;
673 case kAecmSpeakerphone:
674 aecmMode = EchoControlMobile::kSpeakerphone;
675 break;
676 case kAecmLoudSpeakerphone:
677 aecmMode = EchoControlMobile::kLoudSpeakerphone;
678 break;
679 }
680
681
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000682 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000683 set_routing_mode(aecmMode) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000684 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000685 "SetAECMMode() failed to set AECM routing mode");
686 return -1;
687 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000688 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000689 enable_comfort_noise(enableCNG) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000690 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000691 "SetAECMMode() failed to set comfort noise state for AECM");
692 return -1;
693 }
694
695 return 0;
696#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000697 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000698 "SetAECMMode() EC is not supported");
699 return -1;
700#endif
701}
702
703int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000704 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000705 "GetAECMMode(mode=?)");
706#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000707 if (!_shared->statistics().Initialized()) {
708 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000709 return -1;
710 }
711
712 enabledCNG = false;
713
714 EchoControlMobile::RoutingMode aecmMode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000715 _shared->audio_processing()->echo_control_mobile()->routing_mode();
716 enabledCNG = _shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000717 is_comfort_noise_enabled();
718
719 switch (aecmMode) {
720 case EchoControlMobile::kQuietEarpieceOrHeadset:
721 mode = kAecmQuietEarpieceOrHeadset;
722 break;
723 case EchoControlMobile::kEarpiece:
724 mode = kAecmEarpiece;
725 break;
726 case EchoControlMobile::kLoudEarpiece:
727 mode = kAecmLoudEarpiece;
728 break;
729 case EchoControlMobile::kSpeakerphone:
730 mode = kAecmSpeakerphone;
731 break;
732 case EchoControlMobile::kLoudSpeakerphone:
733 mode = kAecmLoudSpeakerphone;
734 break;
735 }
736
737 return 0;
738#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000739 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000740 "GetAECMMode() EC is not supported");
741 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000742#endif
743}
744
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000745int VoEAudioProcessingImpl::EnableHighPassFilter(bool enable) {
746 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
747 "EnableHighPassFilter(%d)", enable);
748 if (_shared->audio_processing()->high_pass_filter()->Enable(enable) !=
749 AudioProcessing::kNoError) {
750 _shared->SetLastError(VE_APM_ERROR, kTraceError,
751 "HighPassFilter::Enable() failed.");
752 return -1;
753 }
754
755 return 0;
756}
757
758bool VoEAudioProcessingImpl::IsHighPassFilterEnabled() {
759 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
760 "IsHighPassFilterEnabled()");
761 return _shared->audio_processing()->high_pass_filter()->is_enabled();
762}
763
niklase@google.com470e71d2011-07-07 08:21:25 +0000764int VoEAudioProcessingImpl::RegisterRxVadObserver(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000765 int channel,
766 VoERxVadCallback& observer) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000767 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000768 "RegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000769 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000770 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000771
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000772 if (!_shared->statistics().Initialized()) {
773 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000774 return -1;
775 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000776 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000777 voe::Channel* channelPtr = sc.ChannelPtr();
778 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000779 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000780 "RegisterRxVadObserver() failed to locate channel");
781 return -1;
782 }
783 return channelPtr->RegisterRxVadObserver(observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000784}
785
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000786int VoEAudioProcessingImpl::DeRegisterRxVadObserver(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000787 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000788 "DeRegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000789 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000790 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000791
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000792 if (!_shared->statistics().Initialized()) {
793 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000794 return -1;
795 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000796 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000797 voe::Channel* channelPtr = sc.ChannelPtr();
798 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000799 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000800 "DeRegisterRxVadObserver() failed to locate channel");
801 return -1;
802 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000803
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000804 return channelPtr->DeRegisterRxVadObserver();
niklase@google.com470e71d2011-07-07 08:21:25 +0000805}
806
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000807int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000808 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000809 "VoiceActivityIndicator(channel=%d)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000810 if (!_shared->statistics().Initialized()) {
811 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000812 return -1;
813 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000814
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000815 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000816 voe::Channel* channelPtr = sc.ChannelPtr();
817 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000818 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000819 "DeRegisterRxVadObserver() failed to locate channel");
820 return -1;
821 }
822 int activity(-1);
823 channelPtr->VoiceActivityIndicator(activity);
niklase@google.com470e71d2011-07-07 08:21:25 +0000824
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000825 return activity;
niklase@google.com470e71d2011-07-07 08:21:25 +0000826}
827
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000828int VoEAudioProcessingImpl::SetEcMetricsStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000829 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000830 "SetEcMetricsStatus(enable=%d)", enable);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000831 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000832 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000833
bjornv@google.com0beae672011-09-28 14:08:19 +0000834#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000835 if (!_shared->statistics().Initialized()) {
836 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000837 return -1;
838 }
839
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000840 if ((_shared->audio_processing()->echo_cancellation()->enable_metrics(enable)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000841 != 0) ||
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000842 (_shared->audio_processing()->echo_cancellation()->enable_delay_logging(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000843 enable) != 0)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000844 _shared->SetLastError(VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000845 "SetEcMetricsStatus() unable to set EC metrics mode");
bjornv@google.com0beae672011-09-28 14:08:19 +0000846 return -1;
847 }
848 return 0;
849#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000850 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000851 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000852 return -1;
853#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000854}
855
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000856int VoEAudioProcessingImpl::GetEcMetricsStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000857 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000858 "GetEcMetricsStatus(enabled=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000859 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000860 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000861
bjornv@google.com0beae672011-09-28 14:08:19 +0000862#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000863 if (!_shared->statistics().Initialized()) {
864 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000865 return -1;
866 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000867
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000868 bool echo_mode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000869 _shared->audio_processing()->echo_cancellation()->are_metrics_enabled();
870 bool delay_mode = _shared->audio_processing()->echo_cancellation()->
871 is_delay_logging_enabled();
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000872
873 if (echo_mode != delay_mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000874 _shared->SetLastError(VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000875 "GetEcMetricsStatus() delay logging and echo mode are not the same");
876 return -1;
877 }
878
879 enabled = echo_mode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000880
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000881 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000882 "GetEcMetricsStatus() => enabled=%d", enabled);
bjornv@google.com0beae672011-09-28 14:08:19 +0000883 return 0;
884#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000885 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000886 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000887 return -1;
888#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000889}
890
891int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
892 int& ERLE,
893 int& RERL,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000894 int& A_NLP) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000895 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000896 "GetEchoMetrics(ERL=?, ERLE=?, RERL=?, A_NLP=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000897 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000898 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000899
900#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000901 if (!_shared->statistics().Initialized()) {
902 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000903 return -1;
904 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000905 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
906 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000907 "GetEchoMetrics() AudioProcessingModule AEC is not enabled");
908 return -1;
909 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000910
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000911 // Get Echo Metrics from Audio Processing Module.
912 EchoCancellation::Metrics echoMetrics;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000913 if (_shared->audio_processing()->echo_cancellation()->GetMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000914 &echoMetrics)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000915 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000916 "GetEchoMetrics(), AudioProcessingModule metrics error");
917 return -1;
918 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000919
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000920 // Echo quality metrics.
921 ERL = echoMetrics.echo_return_loss.instant;
922 ERLE = echoMetrics.echo_return_loss_enhancement.instant;
923 RERL = echoMetrics.residual_echo_return_loss.instant;
924 A_NLP = echoMetrics.a_nlp.instant;
niklase@google.com470e71d2011-07-07 08:21:25 +0000925
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000926 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000927 "GetEchoMetrics() => ERL=%d, ERLE=%d, RERL=%d, A_NLP=%d",
928 ERL, ERLE, RERL, A_NLP);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000929 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000930#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000931 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000932 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000933 return -1;
934#endif
935}
936
937int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median,
938 int& delay_std) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000939 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000940 "GetEcDelayMetrics(median=?, std=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000941 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000942 IPHONE_NOT_SUPPORTED(_shared->statistics());
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000943
944#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000945 if (!_shared->statistics().Initialized()) {
946 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000947 return -1;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000948 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000949 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
950 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000951 "GetEcDelayMetrics() AudioProcessingModule AEC is not enabled");
952 return -1;
953 }
954
955 int median = 0;
956 int std = 0;
957 // Get delay-logging values from Audio Processing Module.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000958 if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000959 &median, &std)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000960 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000961 "GetEcDelayMetrics(), AudioProcessingModule delay-logging "
962 "error");
963 return -1;
964 }
965
966 // EC delay-logging metrics
967 delay_median = median;
968 delay_std = std;
969
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000970 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000971 "GetEcDelayMetrics() => delay_median=%d, delay_std=%d",
972 delay_median, delay_std);
973 return 0;
974#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000975 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000976 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000977 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000978#endif
979}
980
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000981int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000982 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000983 "StartDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000984 if (!_shared->statistics().Initialized()) {
985 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000986 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000987 }
988
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000989 return _shared->audio_processing()->StartDebugRecording(fileNameUTF8);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000990
991}
992
993int VoEAudioProcessingImpl::StopDebugRecording() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000994 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000995 "StopDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000996 if (!_shared->statistics().Initialized()) {
997 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000998 return -1;
999 }
1000
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001001 return _shared->audio_processing()->StopDebugRecording();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001002}
1003
1004int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001005 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001006 "SetTypingDetectionStatus()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001007 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001008 IPHONE_NOT_SUPPORTED(_shared->statistics());
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001009#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001010 if (!_shared->statistics().Initialized()) {
1011 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001012 return -1;
1013 }
1014
1015 // Just use the VAD state to determine if we should enable typing detection
1016 // or not
1017
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001018 if (_shared->audio_processing()->voice_detection()->Enable(enable)) {
1019 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001020 "SetTypingDetectionStatus() failed to set VAD state");
1021 return -1;
1022 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001023 if (_shared->audio_processing()->voice_detection()->set_likelihood(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001024 VoiceDetection::kVeryLowLikelihood)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001025 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001026 "SetTypingDetectionStatus() failed to set VAD likelihood to low");
1027 return -1;
1028 }
1029
1030 return 0;
1031#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001032 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001033 "SetTypingDetectionStatus is not supported");
1034 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +00001035#endif
1036}
1037
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001038int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001039 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001040 "GetTypingDetectionStatus()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001041 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001042 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +00001043
1044#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001045 if (!_shared->statistics().Initialized()) {
1046 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001047 return -1;
1048 }
1049 // Just use the VAD state to determine if we should enable typing
1050 // detection or not
niklase@google.com470e71d2011-07-07 08:21:25 +00001051
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001052 enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +00001053
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001054 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001055#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001056 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001057 "SetTypingDetectionStatus is not supported");
1058 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +00001059#endif
1060}
1061
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001062
1063int VoEAudioProcessingImpl::TimeSinceLastTyping(int &seconds) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001064 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001065 "TimeSinceLastTyping()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001066 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001067 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001068
1069#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001070 if (!_shared->statistics().Initialized()) {
1071 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001072 return -1;
1073 }
1074 // Check if typing detection is enabled
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001075 bool enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001076 if (enabled)
1077 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001078 _shared->transmit_mixer()->TimeSinceLastTyping(seconds);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001079 return 0;
1080 }
1081 else
1082 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001083 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001084 "SetTypingDetectionStatus is not enabled");
1085 return -1;
1086 }
1087#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001088 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001089 "SetTypingDetectionStatus is not supported");
1090 return -1;
1091#endif
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001092}
1093
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001094int VoEAudioProcessingImpl::SetTypingDetectionParameters(int timeWindow,
1095 int costPerTyping,
1096 int reportingThreshold,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001097 int penaltyDecay,
1098 int typeEventDelay) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001099 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001100 "SetTypingDetectionParameters()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001101 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001102 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001103
1104#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001105 if (!_shared->statistics().Initialized()) {
1106 _shared->statistics().SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001107 return -1;
1108 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001109 return (_shared->transmit_mixer()->SetTypingDetectionParameters(timeWindow,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001110 costPerTyping, reportingThreshold, penaltyDecay, typeEventDelay));
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001111
1112#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001113 _shared->statistics().SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001114 "SetTypingDetectionParameters is not supported");
1115 return -1;
1116#endif
1117
1118}
1119
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001120void VoEAudioProcessingImpl::EnableStereoChannelSwapping(bool enable) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +00001121 LOG_API1(enable);
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001122 _shared->transmit_mixer()->EnableStereoChannelSwapping(enable);
1123}
1124
1125bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
andrew@webrtc.org50419b02012-11-14 19:07:54 +00001126 LOG_API0();
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001127 return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
1128}
1129
niklase@google.com470e71d2011-07-07 08:21:25 +00001130#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
1131
1132} // namespace webrtc