blob: 6390970903e754f38b54728e7b8c06aa3fa0c38e [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"
16#include "trace.h"
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +000017#include "transmit_mixer.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000018#include "voe_errors.h"
19#include "voice_engine_impl.h"
20
andrew@webrtc.org02d71742012-04-24 19:47:00 +000021// TODO(andrew): move to a common place.
22#define WEBRTC_TRACE_VOICE_API() \
23 do { \
24 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, \
25 VoEId(_shared->instance_id(), -1), __FUNCTION__); \
26 } while (0)
27
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +000028#define WEBRTC_VOICE_INIT_CHECK() \
29 do { \
30 if (!_shared->statistics().Initialized()) { \
31 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
32 return -1; \
33 } \
34 } while (0)
35
36#define WEBRTC_VOICE_INIT_CHECK_BOOL() \
37 do { \
38 if (!_shared->statistics().Initialized()) { \
39 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
40 return false; \
41 } \
42 } while (0)
43
44
niklase@google.com470e71d2011-07-07 08:21:25 +000045namespace webrtc {
46
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +000047#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
andrew@webrtc.org80124742012-03-08 17:54:24 +000048static const EcModes kDefaultEcMode = kEcAecm;
49#else
50static const EcModes kDefaultEcMode = kEcAec;
51#endif
52
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000053VoEAudioProcessing* VoEAudioProcessing::GetInterface(VoiceEngine* voiceEngine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000054#ifndef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000055 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000056#else
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000057 if (NULL == voiceEngine) {
58 return NULL;
59 }
60 VoiceEngineImpl* s = reinterpret_cast<VoiceEngineImpl*>(voiceEngine);
tommi@webrtc.orga990e122012-04-26 15:28:22 +000061 s->AddRef();
62 return s;
niklase@google.com470e71d2011-07-07 08:21:25 +000063#endif
64}
65
66#ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
tommi@webrtc.org851becd2012-04-04 14:57:19 +000067VoEAudioProcessingImpl::VoEAudioProcessingImpl(voe::SharedData* shared)
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +000068 : _isAecMode(kDefaultEcMode == kEcAec),
69 _shared(shared) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000070 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000071 "VoEAudioProcessingImpl::VoEAudioProcessingImpl() - ctor");
niklase@google.com470e71d2011-07-07 08:21:25 +000072}
73
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000074VoEAudioProcessingImpl::~VoEAudioProcessingImpl() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000075 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000076 "VoEAudioProcessingImpl::~VoEAudioProcessingImpl() - dtor");
niklase@google.com470e71d2011-07-07 08:21:25 +000077}
78
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000079int VoEAudioProcessingImpl::SetNsStatus(bool enable, NsModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000080 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000081 "SetNsStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +000082#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +000083 if (!_shared->statistics().Initialized()) {
84 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000085 return -1;
86 }
niklase@google.com470e71d2011-07-07 08:21:25 +000087
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000088 NoiseSuppression::Level nsLevel(
89 (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE);
90 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000091 case kNsDefault:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000092 nsLevel = (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE;
93 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000094 case kNsUnchanged:
tommi@webrtc.org851becd2012-04-04 14:57:19 +000095 nsLevel = _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000096 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000097 case kNsConference:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000098 nsLevel = NoiseSuppression::kHigh;
99 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000100 case kNsLowSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000101 nsLevel = NoiseSuppression::kLow;
102 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000103 case kNsModerateSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000104 nsLevel = NoiseSuppression::kModerate;
105 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000106 case kNsHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000107 nsLevel = NoiseSuppression::kHigh;
108 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000109 case kNsVeryHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000110 nsLevel = NoiseSuppression::kVeryHigh;
111 break;
112 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000113
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000114 if (_shared->audio_processing()->noise_suppression()->
115 set_level(nsLevel) != 0) {
116 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000117 "SetNsStatus() failed to set Ns mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000118 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000119 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000120 if (_shared->audio_processing()->noise_suppression()->Enable(enable) != 0) {
121 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000122 "SetNsStatus() failed to set Ns state");
123 return -1;
124 }
125
126 return 0;
127#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000128 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000129 "SetNsStatus() Ns is not supported");
130 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000131#endif
132}
133
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000134int VoEAudioProcessingImpl::GetNsStatus(bool& enabled, NsModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000135 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000136 "GetNsStatus(enabled=?, mode=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000137#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000138 if (!_shared->statistics().Initialized()) {
139 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000140 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000141 }
142
143 bool enable(false);
144 NoiseSuppression::Level nsLevel(
145 (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE);
146
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000147 enable = _shared->audio_processing()->noise_suppression()->is_enabled();
148 nsLevel = _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000149
150 enabled = enable;
151
152 switch (nsLevel) {
153 case NoiseSuppression::kLow:
154 mode = kNsLowSuppression;
155 break;
156 case NoiseSuppression::kModerate:
157 mode = kNsModerateSuppression;
158 break;
159 case NoiseSuppression::kHigh:
160 mode = kNsHighSuppression;
161 break;
162 case NoiseSuppression::kVeryHigh:
163 mode = kNsVeryHighSuppression;
164 break;
165 }
166
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000167 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000168 "GetNsStatus() => enabled=% d, mode=%d", enabled, mode);
169 return 0;
170#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000171 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000172 "GetNsStatus() Ns is not supported");
173 return -1;
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000174#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000175}
176
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000177int VoEAudioProcessingImpl::SetAgcStatus(bool enable, AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000178 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000179 "SetAgcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000180#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000181 if (!_shared->statistics().Initialized()) {
182 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000183 return -1;
184 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000185
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000186#if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000187 if (mode == kAgcAdaptiveAnalog) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000188 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000189 "SetAgcStatus() invalid Agc mode for mobile device");
190 return -1;
191 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000192#endif
193
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000194 GainControl::Mode agcMode(
195 (GainControl::Mode)WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE);
196 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000197 case kAgcDefault:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000198 agcMode = (GainControl::Mode)WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE;
199 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000200 case kAgcUnchanged:
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000201 agcMode = _shared->audio_processing()->gain_control()->mode();;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000202 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000203 case kAgcFixedDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000204 agcMode = GainControl::kFixedDigital;
205 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000206 case kAgcAdaptiveAnalog:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000207 agcMode = GainControl::kAdaptiveAnalog;
208 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000209 case kAgcAdaptiveDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000210 agcMode = GainControl::kAdaptiveDigital;
211 break;
212 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000213
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000214 if (_shared->audio_processing()->gain_control()->set_mode(agcMode) != 0) {
215 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000216 "SetAgcStatus() failed to set Agc mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000217 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000218 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000219 if (_shared->audio_processing()->gain_control()->Enable(enable) != 0) {
220 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000221 "SetAgcStatus() failed to set Agc state");
222 return -1;
223 }
224
225 if (agcMode != GainControl::kFixedDigital) {
226 // Set Agc state in the ADM when adaptive Agc mode has been selected.
227 // Note that we also enable the ADM Agc when Adaptive Digital mode is
228 // used since we want to be able to provide the APM with updated mic
229 // levels when the user modifies the mic level manually.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000230 if (_shared->audio_device()->SetAGC(enable) != 0) {
231 _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000232 kTraceWarning, "SetAgcStatus() failed to set Agc mode");
233 }
234 }
235
236 return 0;
237#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000238 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000239 "SetAgcStatus() Agc is not supported");
240 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000241#endif
242}
243
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000244int VoEAudioProcessingImpl::GetAgcStatus(bool& enabled, AgcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000245 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000246 "GetAgcStatus(enabled=?, mode=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000247#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000248 if (!_shared->statistics().Initialized()) {
249 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000250 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000251 }
252
253 bool enable(false);
254 GainControl::Mode agcMode(
255 (GainControl::Mode)WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE);
256
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000257 enable = _shared->audio_processing()->gain_control()->is_enabled();
258 agcMode = _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000259
260 enabled = enable;
261
262 switch (agcMode) {
263 case GainControl::kFixedDigital:
264 mode = kAgcFixedDigital;
265 break;
266 case GainControl::kAdaptiveAnalog:
267 mode = kAgcAdaptiveAnalog;
268 break;
269 case GainControl::kAdaptiveDigital:
270 mode = kAgcAdaptiveDigital;
271 break;
272 }
273
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000274 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000275 "GetAgcStatus() => enabled=%d, mode=%d", enabled, mode);
276 return 0;
277#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000278 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000279 "GetAgcStatus() Agc is not supported");
280 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000281#endif
282}
283
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000284int VoEAudioProcessingImpl::SetAgcConfig(const AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000285 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000286 "SetAgcConfig()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000287#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000288 if (!_shared->statistics().Initialized()) {
289 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000290 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000291 }
292
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000293 if (_shared->audio_processing()->gain_control()->set_target_level_dbfs(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000294 config.targetLeveldBOv) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000295 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000296 "SetAgcConfig() failed to set target peak |level|"
297 " (or envelope) of the Agc");
298 return -1;
299 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000300 if (_shared->audio_processing()->gain_control()->set_compression_gain_db(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000301 config.digitalCompressionGaindB) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000302 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000303 "SetAgcConfig() failed to set the range in |gain| "
304 "the digital compression stage may apply");
305 return -1;
306 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000307 if (_shared->audio_processing()->gain_control()->enable_limiter(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000308 config.limiterEnable) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000309 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000310 "SetAgcConfig() failed to set hard limiter to the signal");
311 return -1;
312 }
313
314 return 0;
315#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000316 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000317 "SetAgcConfig() EC is not supported");
318 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000319#endif
320}
321
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000322int VoEAudioProcessingImpl::GetAgcConfig(AgcConfig& config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000323 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000324 "GetAgcConfig(config=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000325#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000326 if (!_shared->statistics().Initialized()) {
327 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000328 return -1;
329 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000330
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000331 config.targetLeveldBOv =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000332 _shared->audio_processing()->gain_control()->target_level_dbfs();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000333 config.digitalCompressionGaindB =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000334 _shared->audio_processing()->gain_control()->compression_gain_db();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000335 config.limiterEnable =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000336 _shared->audio_processing()->gain_control()->is_limiter_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000337
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000338 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 "GetAgcConfig() => targetLeveldBOv=%u, "
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000340 "digitalCompressionGaindB=%u, limiterEnable=%d",
341 config.targetLeveldBOv,
342 config.digitalCompressionGaindB,
343 config.limiterEnable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000344
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000345 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000346#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000347 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000348 "GetAgcConfig() EC is not supported");
349 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000350#endif
351}
352
353int VoEAudioProcessingImpl::SetRxNsStatus(int channel,
354 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000355 NsModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000356 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000357 "SetRxNsStatus(channel=%d, enable=%d, mode=%d)",
358 channel, (int)enable, (int)mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000359#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000360 if (!_shared->statistics().Initialized()) {
361 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000362 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000363 }
364
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000365 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000366 voe::Channel* channelPtr = sc.ChannelPtr();
367 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000368 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000369 "SetRxNsStatus() failed to locate channel");
370 return -1;
371 }
372 return channelPtr->SetRxNsStatus(enable, mode);
373#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000374 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000375 "SetRxNsStatus() AGC is not supported");
376 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000377#endif
378}
379
380int VoEAudioProcessingImpl::GetRxNsStatus(int channel,
381 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000382 NsModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000383 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000384 "GetRxNsStatus(channel=%d, enable=?, mode=?)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000385#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000386 if (!_shared->statistics().Initialized()) {
387 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000388 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000389 }
390
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000391 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000392 voe::Channel* channelPtr = sc.ChannelPtr();
393 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000394 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000395 "GetRxNsStatus() failed to locate channel");
396 return -1;
397 }
398 return channelPtr->GetRxNsStatus(enabled, mode);
399#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000400 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000401 "GetRxNsStatus() Agc is not supported");
402 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000403#endif
404}
405
406int VoEAudioProcessingImpl::SetRxAgcStatus(int channel,
407 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000408 AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000409 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000410 "SetRxAgcStatus(channel=%d, enable=%d, mode=%d)",
411 channel, (int)enable, (int)mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000412#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000413 if (!_shared->statistics().Initialized()) {
414 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000415 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000416 }
417
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000418 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000419 voe::Channel* channelPtr = sc.ChannelPtr();
420 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000421 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000422 "SetRxAgcStatus() failed to locate channel");
423 return -1;
424 }
425 return channelPtr->SetRxAgcStatus(enable, mode);
426#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000427 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000428 "SetRxAgcStatus() Agc is not supported");
429 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000430#endif
431}
432
433int VoEAudioProcessingImpl::GetRxAgcStatus(int channel,
434 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000435 AgcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000436 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000437 "GetRxAgcStatus(channel=%d, enable=?, mode=?)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000438#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000439 if (!_shared->statistics().Initialized()) {
440 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000441 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000442 }
443
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000444 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000445 voe::Channel* channelPtr = sc.ChannelPtr();
446 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000447 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000448 "GetRxAgcStatus() failed to locate channel");
449 return -1;
450 }
451 return channelPtr->GetRxAgcStatus(enabled, mode);
452#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000453 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000454 "GetRxAgcStatus() Agc is not supported");
455 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000456#endif
457}
458
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000459int VoEAudioProcessingImpl::SetRxAgcConfig(int channel,
460 const AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000461 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000462 "SetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000463#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000464 if (!_shared->statistics().Initialized()) {
465 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000466 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000467 }
468
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000469 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000470 voe::Channel* channelPtr = sc.ChannelPtr();
471 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000472 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000473 "SetRxAgcConfig() failed to locate channel");
474 return -1;
475 }
476 return channelPtr->SetRxAgcConfig(config);
477#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000478 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000479 "SetRxAgcConfig() Agc is not supported");
480 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000481#endif
482}
483
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000484int VoEAudioProcessingImpl::GetRxAgcConfig(int channel, AgcConfig& config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000485 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000486 "GetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000487#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000488 if (!_shared->statistics().Initialized()) {
489 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000490 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000491 }
492
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000493 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000494 voe::Channel* channelPtr = sc.ChannelPtr();
495 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000496 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000497 "GetRxAgcConfig() failed to locate channel");
498 return -1;
499 }
500 return channelPtr->GetRxAgcConfig(config);
501#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000502 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000503 "GetRxAgcConfig() Agc is not supported");
504 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000505#endif
506}
507
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000508bool VoEAudioProcessing::DriftCompensationSupported() {
509#if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
510 return true;
511#else
512 return false;
513#endif
514}
515
516int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
517 WEBRTC_TRACE_VOICE_API();
518 WEBRTC_VOICE_INIT_CHECK();
519
520 if (!DriftCompensationSupported()) {
521 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
522 "Drift compensation is not supported on this platform.");
523 return -1;
524 }
525
526 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
527 if (aec->enable_drift_compensation(enable) != 0) {
528 _shared->SetLastError(VE_APM_ERROR, kTraceError,
529 "aec->enable_drift_compensation() failed");
530 return -1;
531 }
532 return 0;
533}
534
535bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
536 WEBRTC_TRACE_VOICE_API();
537 WEBRTC_VOICE_INIT_CHECK_BOOL();
538
539 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
540 return aec->is_drift_compensation_enabled();
541}
542
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000543int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000544 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000545 "SetEcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000546#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000547 if (!_shared->statistics().Initialized()) {
548 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000549 return -1;
550 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000551
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000552 // AEC mode
553 if ((mode == kEcDefault) ||
554 (mode == kEcConference) ||
555 (mode == kEcAec) ||
556 ((mode == kEcUnchanged) &&
557 (_isAecMode == true))) {
558 if (enable) {
559 // Disable the AECM before enable the AEC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000560 if (_shared->audio_processing()->echo_control_mobile()->is_enabled()) {
561 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000562 "SetEcStatus() disable AECM before enabling AEC");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000563 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000564 Enable(false) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000565 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000566 "SetEcStatus() failed to disable AECM");
567 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000568 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000569 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000570 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000571 if (_shared->audio_processing()->echo_cancellation()->Enable(enable) != 0) {
572 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000573 "SetEcStatus() failed to set AEC state");
574 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000575 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000576 if (mode == kEcConference) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000577 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000578 set_suppression_level(EchoCancellation::kHighSuppression) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000579 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000580 "SetEcStatus() failed to set aggressiveness to high");
niklase@google.com470e71d2011-07-07 08:21:25 +0000581 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000582 }
583 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000584 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000585 set_suppression_level(
586 EchoCancellation::kModerateSuppression) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000587 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000588 "SetEcStatus() failed to set aggressiveness to moderate");
niklase@google.com470e71d2011-07-07 08:21:25 +0000589 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000590 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000591 }
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000592
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000593 _isAecMode = true;
594 } else if ((mode == kEcAecm) ||
595 ((mode == kEcUnchanged) &&
596 (_isAecMode == false))) {
597 if (enable) {
598 // Disable the AEC before enable the AECM
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000599 if (_shared->audio_processing()->echo_cancellation()->is_enabled()) {
600 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000601 "SetEcStatus() disable AEC before enabling AECM");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000602 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000603 Enable(false) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000604 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000605 "SetEcStatus() failed to disable AEC");
606 return -1;
607 }
608 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000609 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000610 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000611 Enable(enable) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000612 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000613 "SetEcStatus() failed to set AECM state");
614 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000615 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000616 _isAecMode = false;
617 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000618 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000619 "SetEcStatus() invalid EC mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000620 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000621 }
622
623 return 0;
624#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000625 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000626 "SetEcStatus() EC is not supported");
627 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000628#endif
629}
630
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000631int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000632 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000633 "GetEcStatus()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000634#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000635 if (!_shared->statistics().Initialized()) {
636 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000637 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000638 }
639
640 if (_isAecMode == true) {
641 mode = kEcAec;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000642 enabled = _shared->audio_processing()->echo_cancellation()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000643 } else {
644 mode = kEcAecm;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000645 enabled = _shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000646 is_enabled();
647 }
648
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000649 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000650 "GetEcStatus() => enabled=%i, mode=%i",
651 enabled, (int)mode);
652 return 0;
653#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000654 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000655 "GetEcStatus() EC is not supported");
656 return -1;
657#endif
658}
659
660void VoEAudioProcessingImpl::SetDelayOffsetMs(int offset) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000661 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000662 "SetDelayOffsetMs(offset = %d)", offset);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000663 _shared->audio_processing()->set_delay_offset_ms(offset);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000664}
665
666int VoEAudioProcessingImpl::DelayOffsetMs() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000667 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000668 "DelayOffsetMs()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000669 return _shared->audio_processing()->delay_offset_ms();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000670}
671
672int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000673 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000674 "SetAECMMode(mode = %d)", mode);
675#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000676 if (!_shared->statistics().Initialized()) {
677 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000678 return -1;
679 }
680
681 EchoControlMobile::RoutingMode aecmMode(
682 EchoControlMobile::kQuietEarpieceOrHeadset);
683
684 switch (mode) {
685 case kAecmQuietEarpieceOrHeadset:
686 aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
687 break;
688 case kAecmEarpiece:
689 aecmMode = EchoControlMobile::kEarpiece;
690 break;
691 case kAecmLoudEarpiece:
692 aecmMode = EchoControlMobile::kLoudEarpiece;
693 break;
694 case kAecmSpeakerphone:
695 aecmMode = EchoControlMobile::kSpeakerphone;
696 break;
697 case kAecmLoudSpeakerphone:
698 aecmMode = EchoControlMobile::kLoudSpeakerphone;
699 break;
700 }
701
702
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000703 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000704 set_routing_mode(aecmMode) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000705 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000706 "SetAECMMode() failed to set AECM routing mode");
707 return -1;
708 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000709 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000710 enable_comfort_noise(enableCNG) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000711 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000712 "SetAECMMode() failed to set comfort noise state for AECM");
713 return -1;
714 }
715
716 return 0;
717#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000718 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000719 "SetAECMMode() EC is not supported");
720 return -1;
721#endif
722}
723
724int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000725 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000726 "GetAECMMode(mode=?)");
727#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000728 if (!_shared->statistics().Initialized()) {
729 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000730 return -1;
731 }
732
733 enabledCNG = false;
734
735 EchoControlMobile::RoutingMode aecmMode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000736 _shared->audio_processing()->echo_control_mobile()->routing_mode();
737 enabledCNG = _shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000738 is_comfort_noise_enabled();
739
740 switch (aecmMode) {
741 case EchoControlMobile::kQuietEarpieceOrHeadset:
742 mode = kAecmQuietEarpieceOrHeadset;
743 break;
744 case EchoControlMobile::kEarpiece:
745 mode = kAecmEarpiece;
746 break;
747 case EchoControlMobile::kLoudEarpiece:
748 mode = kAecmLoudEarpiece;
749 break;
750 case EchoControlMobile::kSpeakerphone:
751 mode = kAecmSpeakerphone;
752 break;
753 case EchoControlMobile::kLoudSpeakerphone:
754 mode = kAecmLoudSpeakerphone;
755 break;
756 }
757
758 return 0;
759#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000760 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000761 "GetAECMMode() EC is not supported");
762 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000763#endif
764}
765
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000766int VoEAudioProcessingImpl::EnableHighPassFilter(bool enable) {
767 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
768 "EnableHighPassFilter(%d)", enable);
769 if (_shared->audio_processing()->high_pass_filter()->Enable(enable) !=
770 AudioProcessing::kNoError) {
771 _shared->SetLastError(VE_APM_ERROR, kTraceError,
772 "HighPassFilter::Enable() failed.");
773 return -1;
774 }
775
776 return 0;
777}
778
779bool VoEAudioProcessingImpl::IsHighPassFilterEnabled() {
780 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
781 "IsHighPassFilterEnabled()");
782 return _shared->audio_processing()->high_pass_filter()->is_enabled();
783}
784
niklase@google.com470e71d2011-07-07 08:21:25 +0000785int VoEAudioProcessingImpl::RegisterRxVadObserver(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000786 int channel,
787 VoERxVadCallback& observer) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000788 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000789 "RegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000790 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000791 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000792
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000793 if (!_shared->statistics().Initialized()) {
794 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000795 return -1;
796 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000797 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000798 voe::Channel* channelPtr = sc.ChannelPtr();
799 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000800 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000801 "RegisterRxVadObserver() failed to locate channel");
802 return -1;
803 }
804 return channelPtr->RegisterRxVadObserver(observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000805}
806
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000807int VoEAudioProcessingImpl::DeRegisterRxVadObserver(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 "DeRegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000810 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000811 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000812
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000813 if (!_shared->statistics().Initialized()) {
814 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000815 return -1;
816 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000817 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000818 voe::Channel* channelPtr = sc.ChannelPtr();
819 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000820 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000821 "DeRegisterRxVadObserver() failed to locate channel");
822 return -1;
823 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000824
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000825 return channelPtr->DeRegisterRxVadObserver();
niklase@google.com470e71d2011-07-07 08:21:25 +0000826}
827
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000828int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000829 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000830 "VoiceActivityIndicator(channel=%d)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000831 if (!_shared->statistics().Initialized()) {
832 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000833 return -1;
834 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000835
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000836 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000837 voe::Channel* channelPtr = sc.ChannelPtr();
838 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000839 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000840 "DeRegisterRxVadObserver() failed to locate channel");
841 return -1;
842 }
843 int activity(-1);
844 channelPtr->VoiceActivityIndicator(activity);
niklase@google.com470e71d2011-07-07 08:21:25 +0000845
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000846 return activity;
niklase@google.com470e71d2011-07-07 08:21:25 +0000847}
848
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000849int VoEAudioProcessingImpl::SetEcMetricsStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000850 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000851 "SetEcMetricsStatus(enable=%d)", enable);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000852 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000853 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000854
bjornv@google.com0beae672011-09-28 14:08:19 +0000855#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000856 if (!_shared->statistics().Initialized()) {
857 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000858 return -1;
859 }
860
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000861 if ((_shared->audio_processing()->echo_cancellation()->enable_metrics(enable)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000862 != 0) ||
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000863 (_shared->audio_processing()->echo_cancellation()->enable_delay_logging(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000864 enable) != 0)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000865 _shared->SetLastError(VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000866 "SetEcMetricsStatus() unable to set EC metrics mode");
bjornv@google.com0beae672011-09-28 14:08:19 +0000867 return -1;
868 }
869 return 0;
870#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000871 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000872 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000873 return -1;
874#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000875}
876
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000877int VoEAudioProcessingImpl::GetEcMetricsStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000878 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000879 "GetEcMetricsStatus(enabled=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000880 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000881 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000882
bjornv@google.com0beae672011-09-28 14:08:19 +0000883#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000884 if (!_shared->statistics().Initialized()) {
885 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000886 return -1;
887 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000888
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000889 bool echo_mode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000890 _shared->audio_processing()->echo_cancellation()->are_metrics_enabled();
891 bool delay_mode = _shared->audio_processing()->echo_cancellation()->
892 is_delay_logging_enabled();
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000893
894 if (echo_mode != delay_mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000895 _shared->SetLastError(VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000896 "GetEcMetricsStatus() delay logging and echo mode are not the same");
897 return -1;
898 }
899
900 enabled = echo_mode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000901
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000902 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000903 "GetEcMetricsStatus() => enabled=%d", enabled);
bjornv@google.com0beae672011-09-28 14:08:19 +0000904 return 0;
905#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000906 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000907 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000908 return -1;
909#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000910}
911
912int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
913 int& ERLE,
914 int& RERL,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000915 int& A_NLP) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000916 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000917 "GetEchoMetrics(ERL=?, ERLE=?, RERL=?, A_NLP=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000918 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000919 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000920
921#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000922 if (!_shared->statistics().Initialized()) {
923 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000924 return -1;
925 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000926 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
927 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000928 "GetEchoMetrics() AudioProcessingModule AEC is not enabled");
929 return -1;
930 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000931
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000932 // Get Echo Metrics from Audio Processing Module.
933 EchoCancellation::Metrics echoMetrics;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000934 if (_shared->audio_processing()->echo_cancellation()->GetMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000935 &echoMetrics)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000936 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000937 "GetEchoMetrics(), AudioProcessingModule metrics error");
938 return -1;
939 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000940
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000941 // Echo quality metrics.
942 ERL = echoMetrics.echo_return_loss.instant;
943 ERLE = echoMetrics.echo_return_loss_enhancement.instant;
944 RERL = echoMetrics.residual_echo_return_loss.instant;
945 A_NLP = echoMetrics.a_nlp.instant;
niklase@google.com470e71d2011-07-07 08:21:25 +0000946
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000947 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000948 "GetEchoMetrics() => ERL=%d, ERLE=%d, RERL=%d, A_NLP=%d",
949 ERL, ERLE, RERL, A_NLP);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000950 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000951#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000952 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000953 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000954 return -1;
955#endif
956}
957
958int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median,
959 int& delay_std) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000960 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000961 "GetEcDelayMetrics(median=?, std=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000962 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000963 IPHONE_NOT_SUPPORTED(_shared->statistics());
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000964
965#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000966 if (!_shared->statistics().Initialized()) {
967 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000968 return -1;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000969 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000970 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
971 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000972 "GetEcDelayMetrics() AudioProcessingModule AEC is not enabled");
973 return -1;
974 }
975
976 int median = 0;
977 int std = 0;
978 // Get delay-logging values from Audio Processing Module.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000979 if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000980 &median, &std)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000981 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000982 "GetEcDelayMetrics(), AudioProcessingModule delay-logging "
983 "error");
984 return -1;
985 }
986
987 // EC delay-logging metrics
988 delay_median = median;
989 delay_std = std;
990
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000991 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000992 "GetEcDelayMetrics() => delay_median=%d, delay_std=%d",
993 delay_median, delay_std);
994 return 0;
995#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000996 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000997 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000998 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000999#endif
1000}
1001
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001002int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001003 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +00001004 "StartDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001005 if (!_shared->statistics().Initialized()) {
1006 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +00001007 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001008 }
1009
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001010 return _shared->audio_processing()->StartDebugRecording(fileNameUTF8);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001011
1012}
1013
1014int VoEAudioProcessingImpl::StopDebugRecording() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001015 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001016 "StopDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001017 if (!_shared->statistics().Initialized()) {
1018 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001019 return -1;
1020 }
1021
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001022 return _shared->audio_processing()->StopDebugRecording();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001023}
1024
1025int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001026 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001027 "SetTypingDetectionStatus()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001028 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001029 IPHONE_NOT_SUPPORTED(_shared->statistics());
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001030#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001031 if (!_shared->statistics().Initialized()) {
1032 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001033 return -1;
1034 }
1035
1036 // Just use the VAD state to determine if we should enable typing detection
1037 // or not
1038
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001039 if (_shared->audio_processing()->voice_detection()->Enable(enable)) {
1040 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001041 "SetTypingDetectionStatus() failed to set VAD state");
1042 return -1;
1043 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001044 if (_shared->audio_processing()->voice_detection()->set_likelihood(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001045 VoiceDetection::kVeryLowLikelihood)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001046 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001047 "SetTypingDetectionStatus() failed to set VAD likelihood to low");
1048 return -1;
1049 }
1050
1051 return 0;
1052#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001053 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001054 "SetTypingDetectionStatus is not supported");
1055 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +00001056#endif
1057}
1058
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001059int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001060 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001061 "GetTypingDetectionStatus()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001062 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001063 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +00001064
1065#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001066 if (!_shared->statistics().Initialized()) {
1067 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001068 return -1;
1069 }
1070 // Just use the VAD state to determine if we should enable typing
1071 // detection or not
niklase@google.com470e71d2011-07-07 08:21:25 +00001072
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001073 enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +00001074
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001075 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001076#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001077 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001078 "SetTypingDetectionStatus is not supported");
1079 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +00001080#endif
1081}
1082
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001083
1084int VoEAudioProcessingImpl::TimeSinceLastTyping(int &seconds) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001085 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001086 "TimeSinceLastTyping()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001087 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001088 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001089
1090#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001091 if (!_shared->statistics().Initialized()) {
1092 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001093 return -1;
1094 }
1095 // Check if typing detection is enabled
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001096 bool enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001097 if (enabled)
1098 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001099 _shared->transmit_mixer()->TimeSinceLastTyping(seconds);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001100 return 0;
1101 }
1102 else
1103 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001104 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001105 "SetTypingDetectionStatus is not enabled");
1106 return -1;
1107 }
1108#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001109 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001110 "SetTypingDetectionStatus is not supported");
1111 return -1;
1112#endif
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001113}
1114
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001115int VoEAudioProcessingImpl::SetTypingDetectionParameters(int timeWindow,
1116 int costPerTyping,
1117 int reportingThreshold,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001118 int penaltyDecay,
1119 int typeEventDelay) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001120 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001121 "SetTypingDetectionParameters()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001122 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001123 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001124
1125#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001126 if (!_shared->statistics().Initialized()) {
1127 _shared->statistics().SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001128 return -1;
1129 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001130 return (_shared->transmit_mixer()->SetTypingDetectionParameters(timeWindow,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001131 costPerTyping, reportingThreshold, penaltyDecay, typeEventDelay));
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001132
1133#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001134 _shared->statistics().SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001135 "SetTypingDetectionParameters is not supported");
1136 return -1;
1137#endif
1138
1139}
1140
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001141void VoEAudioProcessingImpl::EnableStereoChannelSwapping(bool enable) {
1142 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
1143 "EnableStereoChannelSwapping(enable=%d)", enable);
1144 _shared->transmit_mixer()->EnableStereoChannelSwapping(enable);
1145}
1146
1147bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
1148 WEBRTC_TRACE_VOICE_API();
1149 return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
1150}
1151
niklase@google.com470e71d2011-07-07 08:21:25 +00001152#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
1153
1154} // namespace webrtc