blob: 9397bfaf086fa0258615bb2e6d7f5cfdc0a9eff3 [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 }
54 VoiceEngineImpl* s = reinterpret_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.org8b111eb2012-03-06 19:50:12 +000082 NoiseSuppression::Level nsLevel(
83 (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE);
84 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000085 case kNsDefault:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000086 nsLevel = (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE;
87 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000088 case kNsUnchanged:
tommi@webrtc.org851becd2012-04-04 14:57:19 +000089 nsLevel = _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000090 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000091 case kNsConference:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000092 nsLevel = NoiseSuppression::kHigh;
93 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000094 case kNsLowSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000095 nsLevel = NoiseSuppression::kLow;
96 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000097 case kNsModerateSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000098 nsLevel = NoiseSuppression::kModerate;
99 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000100 case kNsHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000101 nsLevel = NoiseSuppression::kHigh;
102 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000103 case kNsVeryHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000104 nsLevel = NoiseSuppression::kVeryHigh;
105 break;
106 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000107
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000108 if (_shared->audio_processing()->noise_suppression()->
109 set_level(nsLevel) != 0) {
110 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000111 "SetNsStatus() failed to set Ns mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000112 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000113 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000114 if (_shared->audio_processing()->noise_suppression()->Enable(enable) != 0) {
115 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000116 "SetNsStatus() failed to set Ns state");
117 return -1;
118 }
119
120 return 0;
121#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000122 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000123 "SetNsStatus() Ns is not supported");
124 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000125#endif
126}
127
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000128int VoEAudioProcessingImpl::GetNsStatus(bool& enabled, NsModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000129 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000130 "GetNsStatus(enabled=?, mode=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000131#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000132 if (!_shared->statistics().Initialized()) {
133 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000134 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000135 }
136
137 bool enable(false);
138 NoiseSuppression::Level nsLevel(
139 (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE);
140
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000141 enable = _shared->audio_processing()->noise_suppression()->is_enabled();
142 nsLevel = _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000143
144 enabled = enable;
145
146 switch (nsLevel) {
147 case NoiseSuppression::kLow:
148 mode = kNsLowSuppression;
149 break;
150 case NoiseSuppression::kModerate:
151 mode = kNsModerateSuppression;
152 break;
153 case NoiseSuppression::kHigh:
154 mode = kNsHighSuppression;
155 break;
156 case NoiseSuppression::kVeryHigh:
157 mode = kNsVeryHighSuppression;
158 break;
159 }
160
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000161 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000162 "GetNsStatus() => enabled=% d, mode=%d", enabled, mode);
163 return 0;
164#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000165 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000166 "GetNsStatus() Ns is not supported");
167 return -1;
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000168#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000169}
170
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000171int VoEAudioProcessingImpl::SetAgcStatus(bool enable, AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000172 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000173 "SetAgcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000174#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000175 if (!_shared->statistics().Initialized()) {
176 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000177 return -1;
178 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000179
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000180#if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000181 if (mode == kAgcAdaptiveAnalog) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000182 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000183 "SetAgcStatus() invalid Agc mode for mobile device");
184 return -1;
185 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000186#endif
187
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000188 GainControl::Mode agcMode(
189 (GainControl::Mode)WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE);
190 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000191 case kAgcDefault:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000192 agcMode = (GainControl::Mode)WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE;
193 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000194 case kAgcUnchanged:
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000195 agcMode = _shared->audio_processing()->gain_control()->mode();;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000196 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000197 case kAgcFixedDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000198 agcMode = GainControl::kFixedDigital;
199 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000200 case kAgcAdaptiveAnalog:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000201 agcMode = GainControl::kAdaptiveAnalog;
202 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000203 case kAgcAdaptiveDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000204 agcMode = GainControl::kAdaptiveDigital;
205 break;
206 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000207
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000208 if (_shared->audio_processing()->gain_control()->set_mode(agcMode) != 0) {
209 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000210 "SetAgcStatus() failed to set Agc mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000211 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000212 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000213 if (_shared->audio_processing()->gain_control()->Enable(enable) != 0) {
214 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000215 "SetAgcStatus() failed to set Agc state");
216 return -1;
217 }
218
219 if (agcMode != GainControl::kFixedDigital) {
220 // Set Agc state in the ADM when adaptive Agc mode has been selected.
221 // Note that we also enable the ADM Agc when Adaptive Digital mode is
222 // used since we want to be able to provide the APM with updated mic
223 // levels when the user modifies the mic level manually.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000224 if (_shared->audio_device()->SetAGC(enable) != 0) {
225 _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000226 kTraceWarning, "SetAgcStatus() failed to set Agc mode");
227 }
228 }
229
230 return 0;
231#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000232 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000233 "SetAgcStatus() Agc is not supported");
234 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000235#endif
236}
237
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000238int VoEAudioProcessingImpl::GetAgcStatus(bool& enabled, AgcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000239 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000240 "GetAgcStatus(enabled=?, mode=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000241#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000242 if (!_shared->statistics().Initialized()) {
243 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000244 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000245 }
246
247 bool enable(false);
248 GainControl::Mode agcMode(
249 (GainControl::Mode)WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE);
250
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000251 enable = _shared->audio_processing()->gain_control()->is_enabled();
252 agcMode = _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000253
254 enabled = enable;
255
256 switch (agcMode) {
257 case GainControl::kFixedDigital:
258 mode = kAgcFixedDigital;
259 break;
260 case GainControl::kAdaptiveAnalog:
261 mode = kAgcAdaptiveAnalog;
262 break;
263 case GainControl::kAdaptiveDigital:
264 mode = kAgcAdaptiveDigital;
265 break;
266 }
267
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000268 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000269 "GetAgcStatus() => enabled=%d, mode=%d", enabled, mode);
270 return 0;
271#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000272 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000273 "GetAgcStatus() Agc is not supported");
274 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000275#endif
276}
277
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000278int VoEAudioProcessingImpl::SetAgcConfig(const AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000279 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000280 "SetAgcConfig()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000281#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000282 if (!_shared->statistics().Initialized()) {
283 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000284 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000285 }
286
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000287 if (_shared->audio_processing()->gain_control()->set_target_level_dbfs(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000288 config.targetLeveldBOv) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000289 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000290 "SetAgcConfig() failed to set target peak |level|"
291 " (or envelope) of the Agc");
292 return -1;
293 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000294 if (_shared->audio_processing()->gain_control()->set_compression_gain_db(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000295 config.digitalCompressionGaindB) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000296 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000297 "SetAgcConfig() failed to set the range in |gain| "
298 "the digital compression stage may apply");
299 return -1;
300 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000301 if (_shared->audio_processing()->gain_control()->enable_limiter(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000302 config.limiterEnable) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000303 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000304 "SetAgcConfig() failed to set hard limiter to the signal");
305 return -1;
306 }
307
308 return 0;
309#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000310 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000311 "SetAgcConfig() EC is not supported");
312 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000313#endif
314}
315
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000316int VoEAudioProcessingImpl::GetAgcConfig(AgcConfig& config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000317 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000318 "GetAgcConfig(config=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000319#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000320 if (!_shared->statistics().Initialized()) {
321 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000322 return -1;
323 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000324
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000325 config.targetLeveldBOv =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000326 _shared->audio_processing()->gain_control()->target_level_dbfs();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000327 config.digitalCompressionGaindB =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000328 _shared->audio_processing()->gain_control()->compression_gain_db();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000329 config.limiterEnable =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000330 _shared->audio_processing()->gain_control()->is_limiter_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000331
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000332 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 "GetAgcConfig() => targetLeveldBOv=%u, "
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000334 "digitalCompressionGaindB=%u, limiterEnable=%d",
335 config.targetLeveldBOv,
336 config.digitalCompressionGaindB,
337 config.limiterEnable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000338
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000339 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000340#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000341 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000342 "GetAgcConfig() EC is not supported");
343 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000344#endif
345}
346
347int VoEAudioProcessingImpl::SetRxNsStatus(int channel,
348 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000349 NsModes mode) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000350 LOG_API3(channel, enable, mode);
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000351#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000352 if (!_shared->statistics().Initialized()) {
353 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000354 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000355 }
356
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000357 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000358 voe::Channel* channelPtr = sc.ChannelPtr();
359 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000360 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000361 "SetRxNsStatus() failed to locate channel");
362 return -1;
363 }
364 return channelPtr->SetRxNsStatus(enable, mode);
365#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000366 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000367 "SetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000368 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000369#endif
370}
371
372int VoEAudioProcessingImpl::GetRxNsStatus(int channel,
373 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000374 NsModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000375 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000376 "GetRxNsStatus(channel=%d, enable=?, mode=?)", channel);
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000377#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000378 if (!_shared->statistics().Initialized()) {
379 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000380 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000381 }
382
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000383 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000384 voe::Channel* channelPtr = sc.ChannelPtr();
385 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000386 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000387 "GetRxNsStatus() failed to locate channel");
388 return -1;
389 }
390 return channelPtr->GetRxNsStatus(enabled, mode);
391#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000392 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000393 "GetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000394 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000395#endif
396}
397
398int VoEAudioProcessingImpl::SetRxAgcStatus(int channel,
399 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000400 AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000401 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000402 "SetRxAgcStatus(channel=%d, enable=%d, mode=%d)",
403 channel, (int)enable, (int)mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000404#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000405 if (!_shared->statistics().Initialized()) {
406 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000407 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000408 }
409
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000410 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000411 voe::Channel* channelPtr = sc.ChannelPtr();
412 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000413 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000414 "SetRxAgcStatus() failed to locate channel");
415 return -1;
416 }
417 return channelPtr->SetRxAgcStatus(enable, mode);
418#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000419 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000420 "SetRxAgcStatus() Agc is not supported");
421 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000422#endif
423}
424
425int VoEAudioProcessingImpl::GetRxAgcStatus(int channel,
426 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000427 AgcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000428 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000429 "GetRxAgcStatus(channel=%d, enable=?, mode=?)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000430#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000431 if (!_shared->statistics().Initialized()) {
432 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000433 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000434 }
435
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000436 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000437 voe::Channel* channelPtr = sc.ChannelPtr();
438 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000439 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000440 "GetRxAgcStatus() failed to locate channel");
441 return -1;
442 }
443 return channelPtr->GetRxAgcStatus(enabled, mode);
444#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000445 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000446 "GetRxAgcStatus() Agc is not supported");
447 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000448#endif
449}
450
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000451int VoEAudioProcessingImpl::SetRxAgcConfig(int channel,
452 const AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000453 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000454 "SetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000455#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000456 if (!_shared->statistics().Initialized()) {
457 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000458 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000459 }
460
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000461 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000462 voe::Channel* channelPtr = sc.ChannelPtr();
463 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000464 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000465 "SetRxAgcConfig() failed to locate channel");
466 return -1;
467 }
468 return channelPtr->SetRxAgcConfig(config);
469#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000470 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000471 "SetRxAgcConfig() Agc is not supported");
472 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000473#endif
474}
475
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000476int VoEAudioProcessingImpl::GetRxAgcConfig(int channel, AgcConfig& config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000477 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000478 "GetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000479#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000480 if (!_shared->statistics().Initialized()) {
481 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000482 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000483 }
484
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000485 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000486 voe::Channel* channelPtr = sc.ChannelPtr();
487 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000488 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000489 "GetRxAgcConfig() failed to locate channel");
490 return -1;
491 }
492 return channelPtr->GetRxAgcConfig(config);
493#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000494 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000495 "GetRxAgcConfig() Agc is not supported");
496 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000497#endif
498}
499
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000500bool VoEAudioProcessing::DriftCompensationSupported() {
501#if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
502 return true;
503#else
504 return false;
505#endif
506}
507
508int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000509 LOG_API1(enable);
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000510 WEBRTC_VOICE_INIT_CHECK();
511
512 if (!DriftCompensationSupported()) {
513 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
514 "Drift compensation is not supported on this platform.");
515 return -1;
516 }
517
518 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
519 if (aec->enable_drift_compensation(enable) != 0) {
520 _shared->SetLastError(VE_APM_ERROR, kTraceError,
521 "aec->enable_drift_compensation() failed");
522 return -1;
523 }
524 return 0;
525}
526
527bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000528 LOG_API0();
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000529 WEBRTC_VOICE_INIT_CHECK_BOOL();
530
531 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
532 return aec->is_drift_compensation_enabled();
533}
534
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000535int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000536 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000537 "SetEcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000538#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000539 if (!_shared->statistics().Initialized()) {
540 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000541 return -1;
542 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000543
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000544 // AEC mode
545 if ((mode == kEcDefault) ||
546 (mode == kEcConference) ||
547 (mode == kEcAec) ||
548 ((mode == kEcUnchanged) &&
549 (_isAecMode == true))) {
550 if (enable) {
551 // Disable the AECM before enable the AEC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000552 if (_shared->audio_processing()->echo_control_mobile()->is_enabled()) {
553 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000554 "SetEcStatus() disable AECM before enabling AEC");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000555 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000556 Enable(false) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000557 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000558 "SetEcStatus() failed to disable AECM");
559 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000560 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000561 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000562 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000563 if (_shared->audio_processing()->echo_cancellation()->Enable(enable) != 0) {
564 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000565 "SetEcStatus() failed to set AEC state");
566 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000567 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000568 if (mode == kEcConference) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000569 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000570 set_suppression_level(EchoCancellation::kHighSuppression) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000571 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000572 "SetEcStatus() failed to set aggressiveness to high");
niklase@google.com470e71d2011-07-07 08:21:25 +0000573 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000574 }
575 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000576 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000577 set_suppression_level(
578 EchoCancellation::kModerateSuppression) != 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 moderate");
niklase@google.com470e71d2011-07-07 08:21:25 +0000581 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000582 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000583 }
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000584
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000585 _isAecMode = true;
586 } else if ((mode == kEcAecm) ||
587 ((mode == kEcUnchanged) &&
588 (_isAecMode == false))) {
589 if (enable) {
590 // Disable the AEC before enable the AECM
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000591 if (_shared->audio_processing()->echo_cancellation()->is_enabled()) {
592 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000593 "SetEcStatus() disable AEC before enabling AECM");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000594 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000595 Enable(false) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000596 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000597 "SetEcStatus() failed to disable AEC");
598 return -1;
599 }
600 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000601 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000602 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000603 Enable(enable) != 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 set AECM state");
606 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000607 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000608 _isAecMode = false;
609 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000610 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000611 "SetEcStatus() invalid EC mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000612 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000613 }
614
615 return 0;
616#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000617 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000618 "SetEcStatus() EC is not supported");
619 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000620#endif
621}
622
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000623int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000624 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000625 "GetEcStatus()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000626#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000627 if (!_shared->statistics().Initialized()) {
628 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000629 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000630 }
631
632 if (_isAecMode == true) {
633 mode = kEcAec;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000634 enabled = _shared->audio_processing()->echo_cancellation()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000635 } else {
636 mode = kEcAecm;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000637 enabled = _shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000638 is_enabled();
639 }
640
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000641 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000642 "GetEcStatus() => enabled=%i, mode=%i",
643 enabled, (int)mode);
644 return 0;
645#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000646 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000647 "GetEcStatus() EC is not supported");
648 return -1;
649#endif
650}
651
652void VoEAudioProcessingImpl::SetDelayOffsetMs(int offset) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000653 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000654 "SetDelayOffsetMs(offset = %d)", offset);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000655 _shared->audio_processing()->set_delay_offset_ms(offset);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000656}
657
658int VoEAudioProcessingImpl::DelayOffsetMs() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000659 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000660 "DelayOffsetMs()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000661 return _shared->audio_processing()->delay_offset_ms();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000662}
663
664int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000665 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000666 "SetAECMMode(mode = %d)", mode);
667#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000668 if (!_shared->statistics().Initialized()) {
669 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000670 return -1;
671 }
672
673 EchoControlMobile::RoutingMode aecmMode(
674 EchoControlMobile::kQuietEarpieceOrHeadset);
675
676 switch (mode) {
677 case kAecmQuietEarpieceOrHeadset:
678 aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
679 break;
680 case kAecmEarpiece:
681 aecmMode = EchoControlMobile::kEarpiece;
682 break;
683 case kAecmLoudEarpiece:
684 aecmMode = EchoControlMobile::kLoudEarpiece;
685 break;
686 case kAecmSpeakerphone:
687 aecmMode = EchoControlMobile::kSpeakerphone;
688 break;
689 case kAecmLoudSpeakerphone:
690 aecmMode = EchoControlMobile::kLoudSpeakerphone;
691 break;
692 }
693
694
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000695 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000696 set_routing_mode(aecmMode) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000697 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000698 "SetAECMMode() failed to set AECM routing mode");
699 return -1;
700 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000701 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000702 enable_comfort_noise(enableCNG) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000703 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000704 "SetAECMMode() failed to set comfort noise state for AECM");
705 return -1;
706 }
707
708 return 0;
709#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000710 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000711 "SetAECMMode() EC is not supported");
712 return -1;
713#endif
714}
715
716int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000717 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000718 "GetAECMMode(mode=?)");
719#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000720 if (!_shared->statistics().Initialized()) {
721 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000722 return -1;
723 }
724
725 enabledCNG = false;
726
727 EchoControlMobile::RoutingMode aecmMode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000728 _shared->audio_processing()->echo_control_mobile()->routing_mode();
729 enabledCNG = _shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000730 is_comfort_noise_enabled();
731
732 switch (aecmMode) {
733 case EchoControlMobile::kQuietEarpieceOrHeadset:
734 mode = kAecmQuietEarpieceOrHeadset;
735 break;
736 case EchoControlMobile::kEarpiece:
737 mode = kAecmEarpiece;
738 break;
739 case EchoControlMobile::kLoudEarpiece:
740 mode = kAecmLoudEarpiece;
741 break;
742 case EchoControlMobile::kSpeakerphone:
743 mode = kAecmSpeakerphone;
744 break;
745 case EchoControlMobile::kLoudSpeakerphone:
746 mode = kAecmLoudSpeakerphone;
747 break;
748 }
749
750 return 0;
751#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000752 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000753 "GetAECMMode() EC is not supported");
754 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000755#endif
756}
757
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000758int VoEAudioProcessingImpl::EnableHighPassFilter(bool enable) {
759 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
760 "EnableHighPassFilter(%d)", enable);
761 if (_shared->audio_processing()->high_pass_filter()->Enable(enable) !=
762 AudioProcessing::kNoError) {
763 _shared->SetLastError(VE_APM_ERROR, kTraceError,
764 "HighPassFilter::Enable() failed.");
765 return -1;
766 }
767
768 return 0;
769}
770
771bool VoEAudioProcessingImpl::IsHighPassFilterEnabled() {
772 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
773 "IsHighPassFilterEnabled()");
774 return _shared->audio_processing()->high_pass_filter()->is_enabled();
775}
776
niklase@google.com470e71d2011-07-07 08:21:25 +0000777int VoEAudioProcessingImpl::RegisterRxVadObserver(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000778 int channel,
779 VoERxVadCallback& observer) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000780 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000781 "RegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000782 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000783 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000784
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000785 if (!_shared->statistics().Initialized()) {
786 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000787 return -1;
788 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000789 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000790 voe::Channel* channelPtr = sc.ChannelPtr();
791 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000792 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000793 "RegisterRxVadObserver() failed to locate channel");
794 return -1;
795 }
796 return channelPtr->RegisterRxVadObserver(observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000797}
798
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000799int VoEAudioProcessingImpl::DeRegisterRxVadObserver(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000800 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000801 "DeRegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000802 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000803 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000804
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000805 if (!_shared->statistics().Initialized()) {
806 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000807 return -1;
808 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000809 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000810 voe::Channel* channelPtr = sc.ChannelPtr();
811 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000812 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000813 "DeRegisterRxVadObserver() failed to locate channel");
814 return -1;
815 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000816
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000817 return channelPtr->DeRegisterRxVadObserver();
niklase@google.com470e71d2011-07-07 08:21:25 +0000818}
819
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000820int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000821 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000822 "VoiceActivityIndicator(channel=%d)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000823 if (!_shared->statistics().Initialized()) {
824 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000825 return -1;
826 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000827
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000828 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000829 voe::Channel* channelPtr = sc.ChannelPtr();
830 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000831 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000832 "DeRegisterRxVadObserver() failed to locate channel");
833 return -1;
834 }
835 int activity(-1);
836 channelPtr->VoiceActivityIndicator(activity);
niklase@google.com470e71d2011-07-07 08:21:25 +0000837
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000838 return activity;
niklase@google.com470e71d2011-07-07 08:21:25 +0000839}
840
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000841int VoEAudioProcessingImpl::SetEcMetricsStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000842 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000843 "SetEcMetricsStatus(enable=%d)", enable);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000844 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000845 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000846
bjornv@google.com0beae672011-09-28 14:08:19 +0000847#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000848 if (!_shared->statistics().Initialized()) {
849 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000850 return -1;
851 }
852
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000853 if ((_shared->audio_processing()->echo_cancellation()->enable_metrics(enable)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000854 != 0) ||
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000855 (_shared->audio_processing()->echo_cancellation()->enable_delay_logging(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000856 enable) != 0)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000857 _shared->SetLastError(VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000858 "SetEcMetricsStatus() unable to set EC metrics mode");
bjornv@google.com0beae672011-09-28 14:08:19 +0000859 return -1;
860 }
861 return 0;
862#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000863 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000864 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000865 return -1;
866#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000867}
868
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000869int VoEAudioProcessingImpl::GetEcMetricsStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000870 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000871 "GetEcMetricsStatus(enabled=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000872 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000873 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000874
bjornv@google.com0beae672011-09-28 14:08:19 +0000875#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000876 if (!_shared->statistics().Initialized()) {
877 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000878 return -1;
879 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000880
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000881 bool echo_mode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000882 _shared->audio_processing()->echo_cancellation()->are_metrics_enabled();
883 bool delay_mode = _shared->audio_processing()->echo_cancellation()->
884 is_delay_logging_enabled();
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000885
886 if (echo_mode != delay_mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000887 _shared->SetLastError(VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000888 "GetEcMetricsStatus() delay logging and echo mode are not the same");
889 return -1;
890 }
891
892 enabled = echo_mode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000893
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000894 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000895 "GetEcMetricsStatus() => enabled=%d", enabled);
bjornv@google.com0beae672011-09-28 14:08:19 +0000896 return 0;
897#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000898 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000899 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000900 return -1;
901#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000902}
903
904int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
905 int& ERLE,
906 int& RERL,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000907 int& A_NLP) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000908 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000909 "GetEchoMetrics(ERL=?, ERLE=?, RERL=?, A_NLP=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000910 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000911 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000912
913#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000914 if (!_shared->statistics().Initialized()) {
915 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000916 return -1;
917 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000918 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
919 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000920 "GetEchoMetrics() AudioProcessingModule AEC is not enabled");
921 return -1;
922 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000923
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000924 // Get Echo Metrics from Audio Processing Module.
925 EchoCancellation::Metrics echoMetrics;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000926 if (_shared->audio_processing()->echo_cancellation()->GetMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000927 &echoMetrics)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000928 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000929 "GetEchoMetrics(), AudioProcessingModule metrics error");
930 return -1;
931 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000932
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000933 // Echo quality metrics.
934 ERL = echoMetrics.echo_return_loss.instant;
935 ERLE = echoMetrics.echo_return_loss_enhancement.instant;
936 RERL = echoMetrics.residual_echo_return_loss.instant;
937 A_NLP = echoMetrics.a_nlp.instant;
niklase@google.com470e71d2011-07-07 08:21:25 +0000938
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000939 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000940 "GetEchoMetrics() => ERL=%d, ERLE=%d, RERL=%d, A_NLP=%d",
941 ERL, ERLE, RERL, A_NLP);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000942 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000943#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000944 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000945 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000946 return -1;
947#endif
948}
949
950int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median,
951 int& delay_std) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000952 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000953 "GetEcDelayMetrics(median=?, std=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000954 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000955 IPHONE_NOT_SUPPORTED(_shared->statistics());
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000956
957#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000958 if (!_shared->statistics().Initialized()) {
959 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000960 return -1;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000961 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000962 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
963 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000964 "GetEcDelayMetrics() AudioProcessingModule AEC is not enabled");
965 return -1;
966 }
967
968 int median = 0;
969 int std = 0;
970 // Get delay-logging values from Audio Processing Module.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000971 if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000972 &median, &std)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000973 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000974 "GetEcDelayMetrics(), AudioProcessingModule delay-logging "
975 "error");
976 return -1;
977 }
978
979 // EC delay-logging metrics
980 delay_median = median;
981 delay_std = std;
982
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000983 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000984 "GetEcDelayMetrics() => delay_median=%d, delay_std=%d",
985 delay_median, delay_std);
986 return 0;
987#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000988 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000989 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000990 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000991#endif
992}
993
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000994int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000995 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000996 "StartDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000997 if (!_shared->statistics().Initialized()) {
998 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000999 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001000 }
1001
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001002 return _shared->audio_processing()->StartDebugRecording(fileNameUTF8);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001003
1004}
1005
1006int VoEAudioProcessingImpl::StopDebugRecording() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001007 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001008 "StopDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001009 if (!_shared->statistics().Initialized()) {
1010 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001011 return -1;
1012 }
1013
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001014 return _shared->audio_processing()->StopDebugRecording();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001015}
1016
1017int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001018 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001019 "SetTypingDetectionStatus()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001020 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001021 IPHONE_NOT_SUPPORTED(_shared->statistics());
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001022#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001023 if (!_shared->statistics().Initialized()) {
1024 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001025 return -1;
1026 }
1027
1028 // Just use the VAD state to determine if we should enable typing detection
1029 // or not
1030
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001031 if (_shared->audio_processing()->voice_detection()->Enable(enable)) {
1032 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001033 "SetTypingDetectionStatus() failed to set VAD state");
1034 return -1;
1035 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001036 if (_shared->audio_processing()->voice_detection()->set_likelihood(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001037 VoiceDetection::kVeryLowLikelihood)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001038 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001039 "SetTypingDetectionStatus() failed to set VAD likelihood to low");
1040 return -1;
1041 }
1042
1043 return 0;
1044#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001045 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001046 "SetTypingDetectionStatus is not supported");
1047 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +00001048#endif
1049}
1050
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001051int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001052 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001053 "GetTypingDetectionStatus()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001054 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001055 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +00001056
1057#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001058 if (!_shared->statistics().Initialized()) {
1059 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001060 return -1;
1061 }
1062 // Just use the VAD state to determine if we should enable typing
1063 // detection or not
niklase@google.com470e71d2011-07-07 08:21:25 +00001064
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001065 enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +00001066
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001067 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001068#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001069 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001070 "SetTypingDetectionStatus is not supported");
1071 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +00001072#endif
1073}
1074
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001075
1076int VoEAudioProcessingImpl::TimeSinceLastTyping(int &seconds) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001077 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001078 "TimeSinceLastTyping()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001079 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001080 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001081
1082#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001083 if (!_shared->statistics().Initialized()) {
1084 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001085 return -1;
1086 }
1087 // Check if typing detection is enabled
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001088 bool enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001089 if (enabled)
1090 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001091 _shared->transmit_mixer()->TimeSinceLastTyping(seconds);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001092 return 0;
1093 }
1094 else
1095 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001096 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001097 "SetTypingDetectionStatus is not enabled");
1098 return -1;
1099 }
1100#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001101 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001102 "SetTypingDetectionStatus is not supported");
1103 return -1;
1104#endif
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001105}
1106
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001107int VoEAudioProcessingImpl::SetTypingDetectionParameters(int timeWindow,
1108 int costPerTyping,
1109 int reportingThreshold,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001110 int penaltyDecay,
1111 int typeEventDelay) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001112 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001113 "SetTypingDetectionParameters()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001114 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001115 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001116
1117#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001118 if (!_shared->statistics().Initialized()) {
1119 _shared->statistics().SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001120 return -1;
1121 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001122 return (_shared->transmit_mixer()->SetTypingDetectionParameters(timeWindow,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001123 costPerTyping, reportingThreshold, penaltyDecay, typeEventDelay));
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001124
1125#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001126 _shared->statistics().SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001127 "SetTypingDetectionParameters is not supported");
1128 return -1;
1129#endif
1130
1131}
1132
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001133void VoEAudioProcessingImpl::EnableStereoChannelSwapping(bool enable) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +00001134 LOG_API1(enable);
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001135 _shared->transmit_mixer()->EnableStereoChannelSwapping(enable);
1136}
1137
1138bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
andrew@webrtc.org50419b02012-11-14 19:07:54 +00001139 LOG_API0();
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001140 return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
1141}
1142
niklase@google.com470e71d2011-07-07 08:21:25 +00001143#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
1144
1145} // namespace webrtc