blob: ac491db60b18f33b96fdb62e11a77de5a010f169 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "voe_audio_processing_impl.h"
12
13#include "audio_processing.h"
14#include "channel.h"
15#include "critical_section_wrapper.h"
andrew@webrtc.org50419b02012-11-14 19:07:54 +000016#include "logging.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000017#include "trace.h"
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +000018#include "transmit_mixer.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000019#include "voe_errors.h"
20#include "voice_engine_impl.h"
21
andrew@webrtc.org02d71742012-04-24 19:47:00 +000022// TODO(andrew): move to a common place.
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +000023#define WEBRTC_VOICE_INIT_CHECK() \
24 do { \
25 if (!_shared->statistics().Initialized()) { \
26 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
27 return -1; \
28 } \
29 } while (0)
30
31#define WEBRTC_VOICE_INIT_CHECK_BOOL() \
32 do { \
33 if (!_shared->statistics().Initialized()) { \
34 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
35 return false; \
36 } \
37 } while (0)
38
niklase@google.com470e71d2011-07-07 08:21:25 +000039namespace webrtc {
40
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +000041#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
andrew@webrtc.org80124742012-03-08 17:54:24 +000042static const EcModes kDefaultEcMode = kEcAecm;
43#else
44static const EcModes kDefaultEcMode = kEcAec;
45#endif
46
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000047VoEAudioProcessing* VoEAudioProcessing::GetInterface(VoiceEngine* voiceEngine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000048#ifndef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000049 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000050#else
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000051 if (NULL == voiceEngine) {
52 return NULL;
53 }
tommi@webrtc.org0989fb72013-02-15 15:07:32 +000054 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
tommi@webrtc.orga990e122012-04-26 15:28:22 +000055 s->AddRef();
56 return s;
niklase@google.com470e71d2011-07-07 08:21:25 +000057#endif
58}
59
60#ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
tommi@webrtc.org851becd2012-04-04 14:57:19 +000061VoEAudioProcessingImpl::VoEAudioProcessingImpl(voe::SharedData* shared)
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +000062 : _isAecMode(kDefaultEcMode == kEcAec),
63 _shared(shared) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000064 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000065 "VoEAudioProcessingImpl::VoEAudioProcessingImpl() - ctor");
niklase@google.com470e71d2011-07-07 08:21:25 +000066}
67
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000068VoEAudioProcessingImpl::~VoEAudioProcessingImpl() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000069 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000070 "VoEAudioProcessingImpl::~VoEAudioProcessingImpl() - dtor");
niklase@google.com470e71d2011-07-07 08:21:25 +000071}
72
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000073int VoEAudioProcessingImpl::SetNsStatus(bool enable, NsModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000074 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000075 "SetNsStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +000076#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +000077 if (!_shared->statistics().Initialized()) {
78 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000079 return -1;
80 }
niklase@google.com470e71d2011-07-07 08:21:25 +000081
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000082 NoiseSuppression::Level nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000083 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000084 case kNsDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000085 nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000086 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000087 case kNsUnchanged:
tommi@webrtc.org851becd2012-04-04 14:57:19 +000088 nsLevel = _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000089 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000090 case kNsConference:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000091 nsLevel = NoiseSuppression::kHigh;
92 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000093 case kNsLowSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000094 nsLevel = NoiseSuppression::kLow;
95 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000096 case kNsModerateSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000097 nsLevel = NoiseSuppression::kModerate;
98 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000099 case kNsHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000100 nsLevel = NoiseSuppression::kHigh;
101 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000102 case kNsVeryHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000103 nsLevel = NoiseSuppression::kVeryHigh;
104 break;
105 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000106
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000107 if (_shared->audio_processing()->noise_suppression()->
108 set_level(nsLevel) != 0) {
109 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000110 "SetNsStatus() failed to set Ns mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000111 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000112 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000113 if (_shared->audio_processing()->noise_suppression()->Enable(enable) != 0) {
114 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000115 "SetNsStatus() failed to set Ns state");
116 return -1;
117 }
118
119 return 0;
120#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000121 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000122 "SetNsStatus() Ns is not supported");
123 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000124#endif
125}
126
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000127int VoEAudioProcessingImpl::GetNsStatus(bool& enabled, NsModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000128 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000129 "GetNsStatus(enabled=?, mode=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000130#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000131 if (!_shared->statistics().Initialized()) {
132 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000133 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000134 }
135
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000136 enabled = _shared->audio_processing()->noise_suppression()->is_enabled();
137 NoiseSuppression::Level nsLevel =
138 _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000139
140 switch (nsLevel) {
141 case NoiseSuppression::kLow:
142 mode = kNsLowSuppression;
143 break;
144 case NoiseSuppression::kModerate:
145 mode = kNsModerateSuppression;
146 break;
147 case NoiseSuppression::kHigh:
148 mode = kNsHighSuppression;
149 break;
150 case NoiseSuppression::kVeryHigh:
151 mode = kNsVeryHighSuppression;
152 break;
153 }
154
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000155 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000156 "GetNsStatus() => enabled=% d, mode=%d", enabled, mode);
157 return 0;
158#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000159 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000160 "GetNsStatus() Ns is not supported");
161 return -1;
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000162#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000163}
164
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000165int VoEAudioProcessingImpl::SetAgcStatus(bool enable, AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000166 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000167 "SetAgcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000168#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000169 if (!_shared->statistics().Initialized()) {
170 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000171 return -1;
172 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000173
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000174#if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000175 if (mode == kAgcAdaptiveAnalog) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000176 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000177 "SetAgcStatus() invalid Agc mode for mobile device");
178 return -1;
179 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000180#endif
181
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000182 GainControl::Mode agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000183 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000184 case kAgcDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000185 agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000186 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000187 case kAgcUnchanged:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000188 agcMode = _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000189 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000190 case kAgcFixedDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000191 agcMode = GainControl::kFixedDigital;
192 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000193 case kAgcAdaptiveAnalog:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000194 agcMode = GainControl::kAdaptiveAnalog;
195 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000196 case kAgcAdaptiveDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000197 agcMode = GainControl::kAdaptiveDigital;
198 break;
199 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000200
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000201 if (_shared->audio_processing()->gain_control()->set_mode(agcMode) != 0) {
202 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000203 "SetAgcStatus() failed to set Agc mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000204 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000205 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000206 if (_shared->audio_processing()->gain_control()->Enable(enable) != 0) {
207 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000208 "SetAgcStatus() failed to set Agc state");
209 return -1;
210 }
211
212 if (agcMode != GainControl::kFixedDigital) {
213 // Set Agc state in the ADM when adaptive Agc mode has been selected.
214 // Note that we also enable the ADM Agc when Adaptive Digital mode is
215 // used since we want to be able to provide the APM with updated mic
216 // levels when the user modifies the mic level manually.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000217 if (_shared->audio_device()->SetAGC(enable) != 0) {
218 _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000219 kTraceWarning, "SetAgcStatus() failed to set Agc mode");
220 }
221 }
222
223 return 0;
224#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000225 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000226 "SetAgcStatus() Agc is not supported");
227 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000228#endif
229}
230
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000231int VoEAudioProcessingImpl::GetAgcStatus(bool& enabled, AgcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000232 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000233 "GetAgcStatus(enabled=?, mode=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000234#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000235 if (!_shared->statistics().Initialized()) {
236 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000237 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000238 }
239
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000240 enabled = _shared->audio_processing()->gain_control()->is_enabled();
sjlee@webrtc.orgb4c441a2013-03-25 11:12:20 +0000241 GainControl::Mode agcMode =
242 _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000243
244 switch (agcMode) {
245 case GainControl::kFixedDigital:
246 mode = kAgcFixedDigital;
247 break;
248 case GainControl::kAdaptiveAnalog:
249 mode = kAgcAdaptiveAnalog;
250 break;
251 case GainControl::kAdaptiveDigital:
252 mode = kAgcAdaptiveDigital;
253 break;
254 }
255
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000256 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000257 "GetAgcStatus() => enabled=%d, mode=%d", enabled, mode);
258 return 0;
259#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000260 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000261 "GetAgcStatus() Agc is not supported");
262 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000263#endif
264}
265
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000266int VoEAudioProcessingImpl::SetAgcConfig(const AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000267 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000268 "SetAgcConfig()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000269#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000270 if (!_shared->statistics().Initialized()) {
271 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000272 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000273 }
274
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000275 if (_shared->audio_processing()->gain_control()->set_target_level_dbfs(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000276 config.targetLeveldBOv) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000277 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000278 "SetAgcConfig() failed to set target peak |level|"
279 " (or envelope) of the Agc");
280 return -1;
281 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000282 if (_shared->audio_processing()->gain_control()->set_compression_gain_db(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000283 config.digitalCompressionGaindB) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000284 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000285 "SetAgcConfig() failed to set the range in |gain| "
286 "the digital compression stage may apply");
287 return -1;
288 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000289 if (_shared->audio_processing()->gain_control()->enable_limiter(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000290 config.limiterEnable) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000291 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000292 "SetAgcConfig() failed to set hard limiter to the signal");
293 return -1;
294 }
295
296 return 0;
297#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000298 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000299 "SetAgcConfig() EC is not supported");
300 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000301#endif
302}
303
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000304int VoEAudioProcessingImpl::GetAgcConfig(AgcConfig& config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000305 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000306 "GetAgcConfig(config=?)");
niklase@google.com470e71d2011-07-07 08:21:25 +0000307#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000308 if (!_shared->statistics().Initialized()) {
309 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000310 return -1;
311 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000312
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000313 config.targetLeveldBOv =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000314 _shared->audio_processing()->gain_control()->target_level_dbfs();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000315 config.digitalCompressionGaindB =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000316 _shared->audio_processing()->gain_control()->compression_gain_db();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000317 config.limiterEnable =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000318 _shared->audio_processing()->gain_control()->is_limiter_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000319
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000320 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000321 "GetAgcConfig() => targetLeveldBOv=%u, "
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000322 "digitalCompressionGaindB=%u, limiterEnable=%d",
323 config.targetLeveldBOv,
324 config.digitalCompressionGaindB,
325 config.limiterEnable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000326
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000327 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000328#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000329 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000330 "GetAgcConfig() EC is not supported");
331 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000332#endif
333}
334
335int VoEAudioProcessingImpl::SetRxNsStatus(int channel,
336 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000337 NsModes mode) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000338 LOG_API3(channel, enable, mode);
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000339#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000340 if (!_shared->statistics().Initialized()) {
341 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000343 }
344
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000345 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000346 voe::Channel* channelPtr = sc.ChannelPtr();
347 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000348 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000349 "SetRxNsStatus() failed to locate channel");
350 return -1;
351 }
352 return channelPtr->SetRxNsStatus(enable, mode);
353#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000354 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000355 "SetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000356 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000357#endif
358}
359
360int VoEAudioProcessingImpl::GetRxNsStatus(int channel,
361 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000362 NsModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000363 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000364 "GetRxNsStatus(channel=%d, enable=?, mode=?)", channel);
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000365#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000366 if (!_shared->statistics().Initialized()) {
367 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000368 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000369 }
370
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000371 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000372 voe::Channel* channelPtr = sc.ChannelPtr();
373 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000374 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000375 "GetRxNsStatus() failed to locate channel");
376 return -1;
377 }
378 return channelPtr->GetRxNsStatus(enabled, mode);
379#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000380 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.orgddcc9422012-11-06 18:39:40 +0000381 "GetRxNsStatus() NS is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000382 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000383#endif
384}
385
386int VoEAudioProcessingImpl::SetRxAgcStatus(int channel,
387 bool enable,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000388 AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000389 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000390 "SetRxAgcStatus(channel=%d, enable=%d, mode=%d)",
391 channel, (int)enable, (int)mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000392#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000393 if (!_shared->statistics().Initialized()) {
394 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000395 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000396 }
397
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000398 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000399 voe::Channel* channelPtr = sc.ChannelPtr();
400 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000401 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000402 "SetRxAgcStatus() failed to locate channel");
403 return -1;
404 }
405 return channelPtr->SetRxAgcStatus(enable, mode);
406#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000407 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000408 "SetRxAgcStatus() Agc is not supported");
409 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000410#endif
411}
412
413int VoEAudioProcessingImpl::GetRxAgcStatus(int channel,
414 bool& enabled,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000415 AgcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000416 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000417 "GetRxAgcStatus(channel=%d, enable=?, mode=?)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000418#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000419 if (!_shared->statistics().Initialized()) {
420 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000421 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000422 }
423
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000424 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000425 voe::Channel* channelPtr = sc.ChannelPtr();
426 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000427 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000428 "GetRxAgcStatus() failed to locate channel");
429 return -1;
430 }
431 return channelPtr->GetRxAgcStatus(enabled, mode);
432#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000433 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000434 "GetRxAgcStatus() Agc is not supported");
435 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000436#endif
437}
438
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000439int VoEAudioProcessingImpl::SetRxAgcConfig(int channel,
440 const AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000441 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000442 "SetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000443#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000444 if (!_shared->statistics().Initialized()) {
445 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000446 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000447 }
448
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000449 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000450 voe::Channel* channelPtr = sc.ChannelPtr();
451 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000452 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000453 "SetRxAgcConfig() failed to locate channel");
454 return -1;
455 }
456 return channelPtr->SetRxAgcConfig(config);
457#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000458 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000459 "SetRxAgcConfig() Agc is not supported");
460 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000461#endif
462}
463
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000464int VoEAudioProcessingImpl::GetRxAgcConfig(int channel, AgcConfig& config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000465 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000466 "GetRxAgcConfig(channel=%d)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000467#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000468 if (!_shared->statistics().Initialized()) {
469 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000470 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000471 }
472
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000473 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000474 voe::Channel* channelPtr = sc.ChannelPtr();
475 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000476 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000477 "GetRxAgcConfig() failed to locate channel");
478 return -1;
479 }
480 return channelPtr->GetRxAgcConfig(config);
481#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000482 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000483 "GetRxAgcConfig() Agc is not supported");
484 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000485#endif
486}
487
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000488bool VoEAudioProcessing::DriftCompensationSupported() {
489#if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
490 return true;
491#else
492 return false;
493#endif
494}
495
496int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000497 LOG_API1(enable);
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000498 WEBRTC_VOICE_INIT_CHECK();
499
500 if (!DriftCompensationSupported()) {
501 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
502 "Drift compensation is not supported on this platform.");
503 return -1;
504 }
505
506 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
507 if (aec->enable_drift_compensation(enable) != 0) {
508 _shared->SetLastError(VE_APM_ERROR, kTraceError,
509 "aec->enable_drift_compensation() failed");
510 return -1;
511 }
512 return 0;
513}
514
515bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000516 LOG_API0();
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000517 WEBRTC_VOICE_INIT_CHECK_BOOL();
518
519 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
520 return aec->is_drift_compensation_enabled();
521}
522
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000523int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000524 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000525 "SetEcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000526#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000527 if (!_shared->statistics().Initialized()) {
528 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000529 return -1;
530 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000531
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000532 // AEC mode
533 if ((mode == kEcDefault) ||
534 (mode == kEcConference) ||
535 (mode == kEcAec) ||
536 ((mode == kEcUnchanged) &&
537 (_isAecMode == true))) {
538 if (enable) {
539 // Disable the AECM before enable the AEC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000540 if (_shared->audio_processing()->echo_control_mobile()->is_enabled()) {
541 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000542 "SetEcStatus() disable AECM before enabling AEC");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000543 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000544 Enable(false) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000545 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000546 "SetEcStatus() failed to disable AECM");
547 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000548 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000549 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000550 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000551 if (_shared->audio_processing()->echo_cancellation()->Enable(enable) != 0) {
552 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000553 "SetEcStatus() failed to set AEC state");
554 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000555 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000556 if (mode == kEcConference) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000557 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000558 set_suppression_level(EchoCancellation::kHighSuppression) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000559 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000560 "SetEcStatus() failed to set aggressiveness to high");
niklase@google.com470e71d2011-07-07 08:21:25 +0000561 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000562 }
563 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000564 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000565 set_suppression_level(
566 EchoCancellation::kModerateSuppression) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000567 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000568 "SetEcStatus() failed to set aggressiveness to moderate");
niklase@google.com470e71d2011-07-07 08:21:25 +0000569 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000570 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000571 }
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000572
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000573 _isAecMode = true;
574 } else if ((mode == kEcAecm) ||
575 ((mode == kEcUnchanged) &&
576 (_isAecMode == false))) {
577 if (enable) {
578 // Disable the AEC before enable the AECM
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000579 if (_shared->audio_processing()->echo_cancellation()->is_enabled()) {
580 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000581 "SetEcStatus() disable AEC before enabling AECM");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000582 if (_shared->audio_processing()->echo_cancellation()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000583 Enable(false) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000584 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000585 "SetEcStatus() failed to disable AEC");
586 return -1;
587 }
588 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000589 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000590 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000591 Enable(enable) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000592 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000593 "SetEcStatus() failed to set AECM state");
594 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000595 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000596 _isAecMode = false;
597 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000598 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000599 "SetEcStatus() invalid EC mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000600 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000601 }
602
603 return 0;
604#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000605 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000606 "SetEcStatus() EC is not supported");
607 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000608#endif
609}
610
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000611int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000612 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000613 "GetEcStatus()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000614#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000615 if (!_shared->statistics().Initialized()) {
616 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000617 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000618 }
619
620 if (_isAecMode == true) {
621 mode = kEcAec;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000622 enabled = _shared->audio_processing()->echo_cancellation()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000623 } else {
624 mode = kEcAecm;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000625 enabled = _shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000626 is_enabled();
627 }
628
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000629 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000630 "GetEcStatus() => enabled=%i, mode=%i",
631 enabled, (int)mode);
632 return 0;
633#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000634 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000635 "GetEcStatus() EC is not supported");
636 return -1;
637#endif
638}
639
640void VoEAudioProcessingImpl::SetDelayOffsetMs(int offset) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000641 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000642 "SetDelayOffsetMs(offset = %d)", offset);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000643 _shared->audio_processing()->set_delay_offset_ms(offset);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000644}
645
646int VoEAudioProcessingImpl::DelayOffsetMs() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000647 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000648 "DelayOffsetMs()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000649 return _shared->audio_processing()->delay_offset_ms();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000650}
651
652int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG) {
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 "SetAECMMode(mode = %d)", mode);
655#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000656 if (!_shared->statistics().Initialized()) {
657 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000658 return -1;
659 }
660
661 EchoControlMobile::RoutingMode aecmMode(
662 EchoControlMobile::kQuietEarpieceOrHeadset);
663
664 switch (mode) {
665 case kAecmQuietEarpieceOrHeadset:
666 aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
667 break;
668 case kAecmEarpiece:
669 aecmMode = EchoControlMobile::kEarpiece;
670 break;
671 case kAecmLoudEarpiece:
672 aecmMode = EchoControlMobile::kLoudEarpiece;
673 break;
674 case kAecmSpeakerphone:
675 aecmMode = EchoControlMobile::kSpeakerphone;
676 break;
677 case kAecmLoudSpeakerphone:
678 aecmMode = EchoControlMobile::kLoudSpeakerphone;
679 break;
680 }
681
682
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000683 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000684 set_routing_mode(aecmMode) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000685 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000686 "SetAECMMode() failed to set AECM routing mode");
687 return -1;
688 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000689 if (_shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000690 enable_comfort_noise(enableCNG) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000691 _shared->SetLastError(VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000692 "SetAECMMode() failed to set comfort noise state for AECM");
693 return -1;
694 }
695
696 return 0;
697#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000698 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000699 "SetAECMMode() EC is not supported");
700 return -1;
701#endif
702}
703
704int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000705 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000706 "GetAECMMode(mode=?)");
707#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000708 if (!_shared->statistics().Initialized()) {
709 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000710 return -1;
711 }
712
713 enabledCNG = false;
714
715 EchoControlMobile::RoutingMode aecmMode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000716 _shared->audio_processing()->echo_control_mobile()->routing_mode();
717 enabledCNG = _shared->audio_processing()->echo_control_mobile()->
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000718 is_comfort_noise_enabled();
719
720 switch (aecmMode) {
721 case EchoControlMobile::kQuietEarpieceOrHeadset:
722 mode = kAecmQuietEarpieceOrHeadset;
723 break;
724 case EchoControlMobile::kEarpiece:
725 mode = kAecmEarpiece;
726 break;
727 case EchoControlMobile::kLoudEarpiece:
728 mode = kAecmLoudEarpiece;
729 break;
730 case EchoControlMobile::kSpeakerphone:
731 mode = kAecmSpeakerphone;
732 break;
733 case EchoControlMobile::kLoudSpeakerphone:
734 mode = kAecmLoudSpeakerphone;
735 break;
736 }
737
738 return 0;
739#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000740 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000741 "GetAECMMode() EC is not supported");
742 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000743#endif
744}
745
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000746int VoEAudioProcessingImpl::EnableHighPassFilter(bool enable) {
747 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
748 "EnableHighPassFilter(%d)", enable);
749 if (_shared->audio_processing()->high_pass_filter()->Enable(enable) !=
750 AudioProcessing::kNoError) {
751 _shared->SetLastError(VE_APM_ERROR, kTraceError,
752 "HighPassFilter::Enable() failed.");
753 return -1;
754 }
755
756 return 0;
757}
758
759bool VoEAudioProcessingImpl::IsHighPassFilterEnabled() {
760 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
761 "IsHighPassFilterEnabled()");
762 return _shared->audio_processing()->high_pass_filter()->is_enabled();
763}
764
niklase@google.com470e71d2011-07-07 08:21:25 +0000765int VoEAudioProcessingImpl::RegisterRxVadObserver(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000766 int channel,
767 VoERxVadCallback& observer) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000768 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000769 "RegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000770 ANDROID_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000771
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000772 if (!_shared->statistics().Initialized()) {
773 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000774 return -1;
775 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000776 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000777 voe::Channel* channelPtr = sc.ChannelPtr();
778 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000779 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000780 "RegisterRxVadObserver() failed to locate channel");
781 return -1;
782 }
783 return channelPtr->RegisterRxVadObserver(observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000784}
785
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000786int VoEAudioProcessingImpl::DeRegisterRxVadObserver(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000787 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000788 "DeRegisterRxVadObserver()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000789 ANDROID_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000790
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000791 if (!_shared->statistics().Initialized()) {
792 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000793 return -1;
794 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000795 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000796 voe::Channel* channelPtr = sc.ChannelPtr();
797 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000798 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000799 "DeRegisterRxVadObserver() failed to locate channel");
800 return -1;
801 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000802
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000803 return channelPtr->DeRegisterRxVadObserver();
niklase@google.com470e71d2011-07-07 08:21:25 +0000804}
805
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000806int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000807 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000808 "VoiceActivityIndicator(channel=%d)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000809 if (!_shared->statistics().Initialized()) {
810 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000811 return -1;
812 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000813
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000814 voe::ScopedChannel sc(_shared->channel_manager(), channel);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000815 voe::Channel* channelPtr = sc.ChannelPtr();
816 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000817 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000818 "DeRegisterRxVadObserver() failed to locate channel");
819 return -1;
820 }
821 int activity(-1);
822 channelPtr->VoiceActivityIndicator(activity);
niklase@google.com470e71d2011-07-07 08:21:25 +0000823
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000824 return activity;
niklase@google.com470e71d2011-07-07 08:21:25 +0000825}
826
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000827int VoEAudioProcessingImpl::SetEcMetricsStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000828 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000829 "SetEcMetricsStatus(enable=%d)", enable);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000830 ANDROID_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000831
bjornv@google.com0beae672011-09-28 14:08:19 +0000832#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000833 if (!_shared->statistics().Initialized()) {
834 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000835 return -1;
836 }
837
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000838 if ((_shared->audio_processing()->echo_cancellation()->enable_metrics(enable)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000839 != 0) ||
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000840 (_shared->audio_processing()->echo_cancellation()->enable_delay_logging(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000841 enable) != 0)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000842 _shared->SetLastError(VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000843 "SetEcMetricsStatus() unable to set EC metrics mode");
bjornv@google.com0beae672011-09-28 14:08:19 +0000844 return -1;
845 }
846 return 0;
847#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000848 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000849 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000850 return -1;
851#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000852}
853
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000854int VoEAudioProcessingImpl::GetEcMetricsStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000855 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000856 "GetEcMetricsStatus(enabled=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000857 ANDROID_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000858
bjornv@google.com0beae672011-09-28 14:08:19 +0000859#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000860 if (!_shared->statistics().Initialized()) {
861 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000862 return -1;
863 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000864
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000865 bool echo_mode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000866 _shared->audio_processing()->echo_cancellation()->are_metrics_enabled();
867 bool delay_mode = _shared->audio_processing()->echo_cancellation()->
868 is_delay_logging_enabled();
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000869
870 if (echo_mode != delay_mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000871 _shared->SetLastError(VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000872 "GetEcMetricsStatus() delay logging and echo mode are not the same");
873 return -1;
874 }
875
876 enabled = echo_mode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000877
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000878 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000879 "GetEcMetricsStatus() => enabled=%d", enabled);
bjornv@google.com0beae672011-09-28 14:08:19 +0000880 return 0;
881#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000882 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000883 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000884 return -1;
885#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000886}
887
888int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
889 int& ERLE,
890 int& RERL,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000891 int& A_NLP) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000892 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000893 "GetEchoMetrics(ERL=?, ERLE=?, RERL=?, A_NLP=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000894 ANDROID_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000895
896#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000897 if (!_shared->statistics().Initialized()) {
898 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000899 return -1;
900 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000901 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
902 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000903 "GetEchoMetrics() AudioProcessingModule AEC is not enabled");
904 return -1;
905 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000906
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000907 // Get Echo Metrics from Audio Processing Module.
908 EchoCancellation::Metrics echoMetrics;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000909 if (_shared->audio_processing()->echo_cancellation()->GetMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000910 &echoMetrics)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000911 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000912 "GetEchoMetrics(), AudioProcessingModule metrics error");
913 return -1;
914 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000915
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000916 // Echo quality metrics.
917 ERL = echoMetrics.echo_return_loss.instant;
918 ERLE = echoMetrics.echo_return_loss_enhancement.instant;
919 RERL = echoMetrics.residual_echo_return_loss.instant;
920 A_NLP = echoMetrics.a_nlp.instant;
niklase@google.com470e71d2011-07-07 08:21:25 +0000921
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000922 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000923 "GetEchoMetrics() => ERL=%d, ERLE=%d, RERL=%d, A_NLP=%d",
924 ERL, ERLE, RERL, A_NLP);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000925 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000926#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000927 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000928 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000929 return -1;
930#endif
931}
932
933int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median,
934 int& delay_std) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000935 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000936 "GetEcDelayMetrics(median=?, std=?)");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000937 ANDROID_NOT_SUPPORTED(_shared->statistics());
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000938
939#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000940 if (!_shared->statistics().Initialized()) {
941 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000942 return -1;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000943 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000944 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
945 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000946 "GetEcDelayMetrics() AudioProcessingModule AEC is not enabled");
947 return -1;
948 }
949
950 int median = 0;
951 int std = 0;
952 // Get delay-logging values from Audio Processing Module.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000953 if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000954 &median, &std)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000955 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000956 "GetEcDelayMetrics(), AudioProcessingModule delay-logging "
957 "error");
958 return -1;
959 }
960
961 // EC delay-logging metrics
962 delay_median = median;
963 delay_std = std;
964
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000965 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000966 "GetEcDelayMetrics() => delay_median=%d, delay_std=%d",
967 delay_median, delay_std);
968 return 0;
969#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000970 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000971 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000972 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000973#endif
974}
975
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000976int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000977 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000978 "StartDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000979 if (!_shared->statistics().Initialized()) {
980 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000981 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000982 }
983
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000984 return _shared->audio_processing()->StartDebugRecording(fileNameUTF8);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000985}
986
987int VoEAudioProcessingImpl::StopDebugRecording() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000988 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000989 "StopDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000990 if (!_shared->statistics().Initialized()) {
991 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000992 return -1;
993 }
994
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000995 return _shared->audio_processing()->StopDebugRecording();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000996}
997
998int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000999 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001000 "SetTypingDetectionStatus()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001001 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001002 IPHONE_NOT_SUPPORTED(_shared->statistics());
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001003#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001004 if (!_shared->statistics().Initialized()) {
1005 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001006 return -1;
1007 }
1008
1009 // Just use the VAD state to determine if we should enable typing detection
1010 // or not
1011
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001012 if (_shared->audio_processing()->voice_detection()->Enable(enable)) {
1013 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001014 "SetTypingDetectionStatus() failed to set VAD state");
1015 return -1;
1016 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001017 if (_shared->audio_processing()->voice_detection()->set_likelihood(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001018 VoiceDetection::kVeryLowLikelihood)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001019 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001020 "SetTypingDetectionStatus() failed to set VAD likelihood to low");
1021 return -1;
1022 }
1023
1024 return 0;
1025#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001026 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001027 "SetTypingDetectionStatus is not supported");
1028 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +00001029#endif
1030}
1031
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001032int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001033 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001034 "GetTypingDetectionStatus()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001035 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001036 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +00001037
1038#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001039 if (!_shared->statistics().Initialized()) {
1040 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001041 return -1;
1042 }
1043 // Just use the VAD state to determine if we should enable typing
1044 // detection or not
niklase@google.com470e71d2011-07-07 08:21:25 +00001045
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001046 enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +00001047
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001048 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001049#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001050 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +00001051 "SetTypingDetectionStatus is not supported");
1052 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +00001053#endif
1054}
1055
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001056
1057int VoEAudioProcessingImpl::TimeSinceLastTyping(int &seconds) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001058 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001059 "TimeSinceLastTyping()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001060 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001061 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001062
1063#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001064 if (!_shared->statistics().Initialized()) {
1065 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001066 return -1;
1067 }
1068 // Check if typing detection is enabled
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001069 bool enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001070 if (enabled)
1071 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001072 _shared->transmit_mixer()->TimeSinceLastTyping(seconds);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001073 return 0;
1074 }
1075 else
1076 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001077 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001078 "SetTypingDetectionStatus is not enabled");
1079 return -1;
1080 }
1081#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001082 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001083 "SetTypingDetectionStatus is not supported");
1084 return -1;
1085#endif
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +00001086}
1087
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001088int VoEAudioProcessingImpl::SetTypingDetectionParameters(int timeWindow,
1089 int costPerTyping,
1090 int reportingThreshold,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001091 int penaltyDecay,
1092 int typeEventDelay) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001093 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001094 "SetTypingDetectionParameters()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001095 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +00001096 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001097
1098#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001099 if (!_shared->statistics().Initialized()) {
1100 _shared->statistics().SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001101 return -1;
1102 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001103 return (_shared->transmit_mixer()->SetTypingDetectionParameters(timeWindow,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +00001104 costPerTyping, reportingThreshold, penaltyDecay, typeEventDelay));
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001105
1106#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +00001107 _shared->statistics().SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001108 "SetTypingDetectionParameters is not supported");
1109 return -1;
1110#endif
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +00001111}
1112
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001113void VoEAudioProcessingImpl::EnableStereoChannelSwapping(bool enable) {
andrew@webrtc.org50419b02012-11-14 19:07:54 +00001114 LOG_API1(enable);
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001115 _shared->transmit_mixer()->EnableStereoChannelSwapping(enable);
1116}
1117
1118bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
andrew@webrtc.org50419b02012-11-14 19:07:54 +00001119 LOG_API0();
andrew@webrtc.org02d71742012-04-24 19:47:00 +00001120 return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
1121}
1122
niklase@google.com470e71d2011-07-07 08:21:25 +00001123#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
1124
1125} // namespace webrtc