blob: 35bf801ea5267cada2e78c8d29c8ba00a520fd30 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000011#include "webrtc/voice_engine/voe_audio_processing_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbosad856222015-11-27 09:48:36 -080013#include "webrtc/base/logging.h"
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000014#include "webrtc/modules/audio_processing/include/audio_processing.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010015#include "webrtc/system_wrappers/include/trace.h"
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000016#include "webrtc/voice_engine/channel.h"
17#include "webrtc/voice_engine/include/voe_errors.h"
18#include "webrtc/voice_engine/transmit_mixer.h"
19#include "webrtc/voice_engine/voice_engine_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020
andrew@webrtc.org02d71742012-04-24 19:47:00 +000021// TODO(andrew): move to a common place.
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +000022#define WEBRTC_VOICE_INIT_CHECK() \
23 do { \
24 if (!_shared->statistics().Initialized()) { \
25 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
26 return -1; \
27 } \
28 } while (0)
29
30#define WEBRTC_VOICE_INIT_CHECK_BOOL() \
31 do { \
32 if (!_shared->statistics().Initialized()) { \
33 _shared->SetLastError(VE_NOT_INITED, kTraceError); \
34 return false; \
35 } \
36 } while (0)
37
niklase@google.com470e71d2011-07-07 08:21:25 +000038namespace webrtc {
39
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +000040#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
andrew@webrtc.org80124742012-03-08 17:54:24 +000041static const EcModes kDefaultEcMode = kEcAecm;
42#else
43static const EcModes kDefaultEcMode = kEcAec;
44#endif
45
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000046VoEAudioProcessing* VoEAudioProcessing::GetInterface(VoiceEngine* voiceEngine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000047#ifndef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000048 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000049#else
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000050 if (NULL == voiceEngine) {
51 return NULL;
52 }
tommi@webrtc.org0989fb72013-02-15 15:07:32 +000053 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
tommi@webrtc.orga990e122012-04-26 15:28:22 +000054 s->AddRef();
55 return s;
niklase@google.com470e71d2011-07-07 08:21:25 +000056#endif
57}
58
59#ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
tommi@webrtc.org851becd2012-04-04 14:57:19 +000060VoEAudioProcessingImpl::VoEAudioProcessingImpl(voe::SharedData* shared)
Jelena Marusic0d266052015-05-04 14:15:32 +020061 : _isAecMode(kDefaultEcMode == kEcAec), _shared(shared) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000062 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000063 "VoEAudioProcessingImpl::VoEAudioProcessingImpl() - ctor");
niklase@google.com470e71d2011-07-07 08:21:25 +000064}
65
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000066VoEAudioProcessingImpl::~VoEAudioProcessingImpl() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000067 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000068 "VoEAudioProcessingImpl::~VoEAudioProcessingImpl() - dtor");
niklase@google.com470e71d2011-07-07 08:21:25 +000069}
70
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000071int VoEAudioProcessingImpl::SetNsStatus(bool enable, NsModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000072 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000073 "SetNsStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +000074#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +000075 if (!_shared->statistics().Initialized()) {
76 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000077 return -1;
78 }
niklase@google.com470e71d2011-07-07 08:21:25 +000079
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000080 NoiseSuppression::Level nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000081 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000082 case kNsDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +000083 nsLevel = kDefaultNsMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000084 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000085 case kNsUnchanged:
tommi@webrtc.org851becd2012-04-04 14:57:19 +000086 nsLevel = _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000087 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000088 case kNsConference:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000089 nsLevel = NoiseSuppression::kHigh;
90 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000091 case kNsLowSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000092 nsLevel = NoiseSuppression::kLow;
93 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000094 case kNsModerateSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000095 nsLevel = NoiseSuppression::kModerate;
96 break;
niklase@google.com470e71d2011-07-07 08:21:25 +000097 case kNsHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +000098 nsLevel = NoiseSuppression::kHigh;
99 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000100 case kNsVeryHighSuppression:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000101 nsLevel = NoiseSuppression::kVeryHigh;
102 break;
103 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000104
Jelena Marusic0d266052015-05-04 14:15:32 +0200105 if (_shared->audio_processing()->noise_suppression()->set_level(nsLevel) !=
106 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000107 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200108 "SetNsStatus() failed to set Ns mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000109 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000110 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000111 if (_shared->audio_processing()->noise_suppression()->Enable(enable) != 0) {
112 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200113 "SetNsStatus() failed to set Ns state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000114 return -1;
115 }
116
117 return 0;
118#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700119#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000120 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200121 "SetNsStatus() Ns is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000122 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000123#endif
124}
125
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000126int VoEAudioProcessingImpl::GetNsStatus(bool& enabled, NsModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000127#ifdef WEBRTC_VOICE_ENGINE_NR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000128 if (!_shared->statistics().Initialized()) {
129 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000130 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000131 }
132
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000133 enabled = _shared->audio_processing()->noise_suppression()->is_enabled();
134 NoiseSuppression::Level nsLevel =
135 _shared->audio_processing()->noise_suppression()->level();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000136
137 switch (nsLevel) {
138 case NoiseSuppression::kLow:
139 mode = kNsLowSuppression;
140 break;
141 case NoiseSuppression::kModerate:
142 mode = kNsModerateSuppression;
143 break;
144 case NoiseSuppression::kHigh:
145 mode = kNsHighSuppression;
146 break;
147 case NoiseSuppression::kVeryHigh:
148 mode = kNsVeryHighSuppression;
149 break;
150 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000151 return 0;
152#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700153#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000154 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200155 "GetNsStatus() Ns is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000156 return -1;
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000157#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000158}
159
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000160int VoEAudioProcessingImpl::SetAgcStatus(bool enable, AgcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000161 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000162 "SetAgcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000163#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000164 if (!_shared->statistics().Initialized()) {
165 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000166 return -1;
167 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000168
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000169#if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID)
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000170 if (mode == kAgcAdaptiveAnalog) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000171 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200172 "SetAgcStatus() invalid Agc mode for mobile device");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000173 return -1;
174 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000175#endif
176
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000177 GainControl::Mode agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000178 switch (mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000179 case kAgcDefault:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000180 agcMode = kDefaultAgcMode;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000181 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000182 case kAgcUnchanged:
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000183 agcMode = _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000184 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000185 case kAgcFixedDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000186 agcMode = GainControl::kFixedDigital;
187 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000188 case kAgcAdaptiveAnalog:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000189 agcMode = GainControl::kAdaptiveAnalog;
190 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000191 case kAgcAdaptiveDigital:
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000192 agcMode = GainControl::kAdaptiveDigital;
193 break;
194 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000195
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000196 if (_shared->audio_processing()->gain_control()->set_mode(agcMode) != 0) {
197 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200198 "SetAgcStatus() failed to set Agc mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000199 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000200 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000201 if (_shared->audio_processing()->gain_control()->Enable(enable) != 0) {
202 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200203 "SetAgcStatus() failed to set Agc state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000204 return -1;
205 }
206
207 if (agcMode != GainControl::kFixedDigital) {
208 // Set Agc state in the ADM when adaptive Agc mode has been selected.
209 // Note that we also enable the ADM Agc when Adaptive Digital mode is
210 // used since we want to be able to provide the APM with updated mic
211 // levels when the user modifies the mic level manually.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000212 if (_shared->audio_device()->SetAGC(enable) != 0) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200213 _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning,
214 "SetAgcStatus() failed to set Agc mode");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000215 }
216 }
217
218 return 0;
219#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700220#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000221 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200222 "SetAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000223 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000224#endif
225}
226
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000227int VoEAudioProcessingImpl::GetAgcStatus(bool& enabled, AgcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000228#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000229 if (!_shared->statistics().Initialized()) {
230 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000231 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000232 }
233
andrew@webrtc.orgf0a90c32013-03-05 01:12:49 +0000234 enabled = _shared->audio_processing()->gain_control()->is_enabled();
sjlee@webrtc.orgb4c441a2013-03-25 11:12:20 +0000235 GainControl::Mode agcMode =
Jelena Marusic0d266052015-05-04 14:15:32 +0200236 _shared->audio_processing()->gain_control()->mode();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000237
238 switch (agcMode) {
239 case GainControl::kFixedDigital:
240 mode = kAgcFixedDigital;
241 break;
242 case GainControl::kAdaptiveAnalog:
243 mode = kAgcAdaptiveAnalog;
244 break;
245 case GainControl::kAdaptiveDigital:
246 mode = kAgcAdaptiveDigital;
247 break;
248 }
249
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000250 return 0;
251#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700252#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000253 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200254 "GetAgcStatus() Agc is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000255 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000256#endif
257}
258
pbos@webrtc.org92135212013-05-14 08:31:39 +0000259int VoEAudioProcessingImpl::SetAgcConfig(AgcConfig config) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000260 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000261 "SetAgcConfig()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000262#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000263 if (!_shared->statistics().Initialized()) {
264 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000265 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000266 }
267
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000268 if (_shared->audio_processing()->gain_control()->set_target_level_dbfs(
Jelena Marusic0d266052015-05-04 14:15:32 +0200269 config.targetLeveldBOv) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000270 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200271 "SetAgcConfig() failed to set target peak |level|"
272 " (or envelope) of the Agc");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000273 return -1;
274 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000275 if (_shared->audio_processing()->gain_control()->set_compression_gain_db(
Jelena Marusic0d266052015-05-04 14:15:32 +0200276 config.digitalCompressionGaindB) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000277 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200278 "SetAgcConfig() failed to set the range in |gain| "
279 "the digital compression stage may apply");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000280 return -1;
281 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000282 if (_shared->audio_processing()->gain_control()->enable_limiter(
Jelena Marusic0d266052015-05-04 14:15:32 +0200283 config.limiterEnable) != 0) {
284 _shared->SetLastError(
285 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000286 "SetAgcConfig() failed to set hard limiter to the signal");
287 return -1;
288 }
289
290 return 0;
291#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700292#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000293 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200294 "SetAgcConfig() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000295 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000296#endif
297}
298
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000299int VoEAudioProcessingImpl::GetAgcConfig(AgcConfig& config) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000300#ifdef WEBRTC_VOICE_ENGINE_AGC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000301 if (!_shared->statistics().Initialized()) {
302 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000303 return -1;
304 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000305
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000306 config.targetLeveldBOv =
Jelena Marusic0d266052015-05-04 14:15:32 +0200307 _shared->audio_processing()->gain_control()->target_level_dbfs();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000308 config.digitalCompressionGaindB =
Jelena Marusic0d266052015-05-04 14:15:32 +0200309 _shared->audio_processing()->gain_control()->compression_gain_db();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000310 config.limiterEnable =
Jelena Marusic0d266052015-05-04 14:15:32 +0200311 _shared->audio_processing()->gain_control()->is_limiter_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000312
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000313 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000314#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700315#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000316 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200317 "GetAgcConfig() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000318 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000319#endif
320}
321
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000322bool VoEAudioProcessing::DriftCompensationSupported() {
323#if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
324 return true;
325#else
326 return false;
327#endif
328}
329
330int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000331 WEBRTC_VOICE_INIT_CHECK();
332
333 if (!DriftCompensationSupported()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200334 _shared->SetLastError(
335 VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000336 "Drift compensation is not supported on this platform.");
337 return -1;
338 }
339
340 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
341 if (aec->enable_drift_compensation(enable) != 0) {
342 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200343 "aec->enable_drift_compensation() failed");
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000344 return -1;
345 }
346 return 0;
347}
348
349bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
andrew@webrtc.org55c0d4a2012-08-29 02:13:12 +0000350 WEBRTC_VOICE_INIT_CHECK_BOOL();
351
352 EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
353 return aec->is_drift_compensation_enabled();
354}
355
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000356int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000357 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000358 "SetEcStatus(enable=%d, mode=%d)", enable, mode);
niklase@google.com470e71d2011-07-07 08:21:25 +0000359#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000360 if (!_shared->statistics().Initialized()) {
361 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000362 return -1;
363 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000364
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000365 // AEC mode
Jelena Marusic0d266052015-05-04 14:15:32 +0200366 if ((mode == kEcDefault) || (mode == kEcConference) || (mode == kEcAec) ||
367 ((mode == kEcUnchanged) && (_isAecMode == true))) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000368 if (enable) {
369 // Disable the AECM before enable the AEC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000370 if (_shared->audio_processing()->echo_control_mobile()->is_enabled()) {
371 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200372 "SetEcStatus() disable AECM before enabling AEC");
373 if (_shared->audio_processing()->echo_control_mobile()->Enable(false) !=
374 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000375 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200376 "SetEcStatus() failed to disable AECM");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000377 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000378 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000379 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000380 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000381 if (_shared->audio_processing()->echo_cancellation()->Enable(enable) != 0) {
382 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200383 "SetEcStatus() failed to set AEC state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000384 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000385 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000386 if (mode == kEcConference) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200387 if (_shared->audio_processing()
388 ->echo_cancellation()
389 ->set_suppression_level(EchoCancellation::kHighSuppression) !=
390 0) {
391 _shared->SetLastError(
392 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000393 "SetEcStatus() failed to set aggressiveness to high");
niklase@google.com470e71d2011-07-07 08:21:25 +0000394 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000395 }
396 } else {
Jelena Marusic0d266052015-05-04 14:15:32 +0200397 if (_shared->audio_processing()
398 ->echo_cancellation()
399 ->set_suppression_level(EchoCancellation::kModerateSuppression) !=
400 0) {
401 _shared->SetLastError(
402 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000403 "SetEcStatus() failed to set aggressiveness to moderate");
niklase@google.com470e71d2011-07-07 08:21:25 +0000404 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000405 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000406 }
andrew@webrtc.org6f9f8172012-03-06 19:03:39 +0000407
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000408 _isAecMode = true;
409 } else if ((mode == kEcAecm) ||
Jelena Marusic0d266052015-05-04 14:15:32 +0200410 ((mode == kEcUnchanged) && (_isAecMode == false))) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000411 if (enable) {
412 // Disable the AEC before enable the AECM
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000413 if (_shared->audio_processing()->echo_cancellation()->is_enabled()) {
414 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200415 "SetEcStatus() disable AEC before enabling AECM");
416 if (_shared->audio_processing()->echo_cancellation()->Enable(false) !=
417 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000418 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200419 "SetEcStatus() failed to disable AEC");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000420 return -1;
421 }
422 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000423 }
Jelena Marusic0d266052015-05-04 14:15:32 +0200424 if (_shared->audio_processing()->echo_control_mobile()->Enable(enable) !=
425 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000426 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200427 "SetEcStatus() failed to set AECM state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000428 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000429 }
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000430 _isAecMode = false;
431 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000432 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200433 "SetEcStatus() invalid EC mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000434 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000435 }
436
437 return 0;
438#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700439#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000440 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200441 "SetEcStatus() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000442 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000443#endif
444}
445
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000446int VoEAudioProcessingImpl::GetEcStatus(bool& enabled, EcModes& mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000447#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000448 if (!_shared->statistics().Initialized()) {
449 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000450 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000451 }
452
453 if (_isAecMode == true) {
454 mode = kEcAec;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000455 enabled = _shared->audio_processing()->echo_cancellation()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000456 } else {
457 mode = kEcAecm;
Jelena Marusic0d266052015-05-04 14:15:32 +0200458 enabled = _shared->audio_processing()->echo_control_mobile()->is_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000459 }
460
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000461 return 0;
462#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700463#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000464 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200465 "GetEcStatus() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000466 return -1;
467#endif
468}
469
470void VoEAudioProcessingImpl::SetDelayOffsetMs(int offset) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000471 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000472 "SetDelayOffsetMs(offset = %d)", offset);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000473 _shared->audio_processing()->set_delay_offset_ms(offset);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000474}
475
476int VoEAudioProcessingImpl::DelayOffsetMs() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000477 return _shared->audio_processing()->delay_offset_ms();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000478}
479
480int VoEAudioProcessingImpl::SetAecmMode(AecmModes mode, bool enableCNG) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000481 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000482 "SetAECMMode(mode = %d)", mode);
483#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000484 if (!_shared->statistics().Initialized()) {
485 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000486 return -1;
487 }
488
489 EchoControlMobile::RoutingMode aecmMode(
490 EchoControlMobile::kQuietEarpieceOrHeadset);
491
492 switch (mode) {
493 case kAecmQuietEarpieceOrHeadset:
494 aecmMode = EchoControlMobile::kQuietEarpieceOrHeadset;
495 break;
496 case kAecmEarpiece:
497 aecmMode = EchoControlMobile::kEarpiece;
498 break;
499 case kAecmLoudEarpiece:
500 aecmMode = EchoControlMobile::kLoudEarpiece;
501 break;
502 case kAecmSpeakerphone:
503 aecmMode = EchoControlMobile::kSpeakerphone;
504 break;
505 case kAecmLoudSpeakerphone:
506 aecmMode = EchoControlMobile::kLoudSpeakerphone;
507 break;
508 }
509
Jelena Marusic0d266052015-05-04 14:15:32 +0200510 if (_shared->audio_processing()->echo_control_mobile()->set_routing_mode(
511 aecmMode) != 0) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000512 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200513 "SetAECMMode() failed to set AECM routing mode");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000514 return -1;
515 }
Jelena Marusic0d266052015-05-04 14:15:32 +0200516 if (_shared->audio_processing()->echo_control_mobile()->enable_comfort_noise(
517 enableCNG) != 0) {
518 _shared->SetLastError(
519 VE_APM_ERROR, kTraceError,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000520 "SetAECMMode() failed to set comfort noise state for AECM");
521 return -1;
522 }
523
524 return 0;
525#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700526#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000527 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200528 "SetAECMMode() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000529 return -1;
530#endif
531}
532
533int VoEAudioProcessingImpl::GetAecmMode(AecmModes& mode, bool& enabledCNG) {
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000534#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000535 if (!_shared->statistics().Initialized()) {
536 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000537 return -1;
538 }
539
540 enabledCNG = false;
541
542 EchoControlMobile::RoutingMode aecmMode =
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000543 _shared->audio_processing()->echo_control_mobile()->routing_mode();
Jelena Marusic0d266052015-05-04 14:15:32 +0200544 enabledCNG = _shared->audio_processing()
545 ->echo_control_mobile()
546 ->is_comfort_noise_enabled();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000547
548 switch (aecmMode) {
549 case EchoControlMobile::kQuietEarpieceOrHeadset:
550 mode = kAecmQuietEarpieceOrHeadset;
551 break;
552 case EchoControlMobile::kEarpiece:
553 mode = kAecmEarpiece;
554 break;
555 case EchoControlMobile::kLoudEarpiece:
556 mode = kAecmLoudEarpiece;
557 break;
558 case EchoControlMobile::kSpeakerphone:
559 mode = kAecmSpeakerphone;
560 break;
561 case EchoControlMobile::kLoudSpeakerphone:
562 mode = kAecmLoudSpeakerphone;
563 break;
564 }
565
566 return 0;
567#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700568#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000569 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200570 "GetAECMMode() EC is not supported");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000571 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000572#endif
573}
574
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000575int VoEAudioProcessingImpl::EnableHighPassFilter(bool enable) {
576 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
577 "EnableHighPassFilter(%d)", enable);
578 if (_shared->audio_processing()->high_pass_filter()->Enable(enable) !=
579 AudioProcessing::kNoError) {
580 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200581 "HighPassFilter::Enable() failed.");
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000582 return -1;
583 }
584
585 return 0;
586}
587
588bool VoEAudioProcessingImpl::IsHighPassFilterEnabled() {
andrew@webrtc.org369166a2012-04-24 18:38:03 +0000589 return _shared->audio_processing()->high_pass_filter()->is_enabled();
590}
591
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000592int VoEAudioProcessingImpl::VoiceActivityIndicator(int channel) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000593 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000594 "VoiceActivityIndicator(channel=%d)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000595 if (!_shared->statistics().Initialized()) {
596 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000597 return -1;
598 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000599
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000600 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
601 voe::Channel* channelPtr = ch.channel();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000602 if (channelPtr == NULL) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000603 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
solenberg11ace152016-09-15 04:29:13 -0700604 "VoiceActivityIndicator() failed to locate channel");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000605 return -1;
606 }
607 int activity(-1);
608 channelPtr->VoiceActivityIndicator(activity);
niklase@google.com470e71d2011-07-07 08:21:25 +0000609
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000610 return activity;
niklase@google.com470e71d2011-07-07 08:21:25 +0000611}
612
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000613int VoEAudioProcessingImpl::SetEcMetricsStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000614 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000615 "SetEcMetricsStatus(enable=%d)", enable);
bjornv@google.com0beae672011-09-28 14:08:19 +0000616#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000617 if (!_shared->statistics().Initialized()) {
618 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000619 return -1;
620 }
621
Jelena Marusic0d266052015-05-04 14:15:32 +0200622 if ((_shared->audio_processing()->echo_cancellation()->enable_metrics(
623 enable) != 0) ||
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000624 (_shared->audio_processing()->echo_cancellation()->enable_delay_logging(
Jelena Marusic0d266052015-05-04 14:15:32 +0200625 enable) != 0)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000626 _shared->SetLastError(VE_APM_ERROR, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200627 "SetEcMetricsStatus() unable to set EC metrics mode");
bjornv@google.com0beae672011-09-28 14:08:19 +0000628 return -1;
629 }
630 return 0;
631#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700632#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000633 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200634 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000635 return -1;
636#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000637}
638
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000639int VoEAudioProcessingImpl::GetEcMetricsStatus(bool& enabled) {
bjornv@google.com0beae672011-09-28 14:08:19 +0000640#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000641 if (!_shared->statistics().Initialized()) {
642 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@google.com0beae672011-09-28 14:08:19 +0000643 return -1;
644 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000645
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000646 bool echo_mode =
Jelena Marusic0d266052015-05-04 14:15:32 +0200647 _shared->audio_processing()->echo_cancellation()->are_metrics_enabled();
648 bool delay_mode = _shared->audio_processing()
649 ->echo_cancellation()
650 ->is_delay_logging_enabled();
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000651
652 if (echo_mode != delay_mode) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200653 _shared->SetLastError(
654 VE_APM_ERROR, kTraceError,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000655 "GetEcMetricsStatus() delay logging and echo mode are not the same");
656 return -1;
657 }
658
659 enabled = echo_mode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000660
bjornv@google.com0beae672011-09-28 14:08:19 +0000661 return 0;
662#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700663#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000664 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200665 "SetEcStatus() EC is not supported");
bjornv@google.com0beae672011-09-28 14:08:19 +0000666 return -1;
667#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000668}
669
670int VoEAudioProcessingImpl::GetEchoMetrics(int& ERL,
671 int& ERLE,
672 int& RERL,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000673 int& A_NLP) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000674#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000675 if (!_shared->statistics().Initialized()) {
676 _shared->SetLastError(VE_NOT_INITED, kTraceError);
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000677 return -1;
678 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000679 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200680 _shared->SetLastError(
681 VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000682 "GetEchoMetrics() AudioProcessingModule AEC is not enabled");
683 return -1;
684 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000685
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000686 // Get Echo Metrics from Audio Processing Module.
687 EchoCancellation::Metrics echoMetrics;
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000688 if (_shared->audio_processing()->echo_cancellation()->GetMetrics(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000689 &echoMetrics)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000690 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000691 "GetEchoMetrics(), AudioProcessingModule metrics error");
692 return -1;
693 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000694
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000695 // Echo quality metrics.
696 ERL = echoMetrics.echo_return_loss.instant;
697 ERLE = echoMetrics.echo_return_loss_enhancement.instant;
698 RERL = echoMetrics.residual_echo_return_loss.instant;
699 A_NLP = echoMetrics.a_nlp.instant;
niklase@google.com470e71d2011-07-07 08:21:25 +0000700
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000701 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000702#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700703#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000704 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200705 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000706 return -1;
707#endif
708}
709
710int VoEAudioProcessingImpl::GetEcDelayMetrics(int& delay_median,
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000711 int& delay_std,
712 float& fraction_poor_delays) {
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000713#ifdef WEBRTC_VOICE_ENGINE_ECHO
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000714 if (!_shared->statistics().Initialized()) {
715 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000716 return -1;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000717 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000718 if (!_shared->audio_processing()->echo_cancellation()->is_enabled()) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200719 _shared->SetLastError(
720 VE_APM_ERROR, kTraceWarning,
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000721 "GetEcDelayMetrics() AudioProcessingModule AEC is not enabled");
722 return -1;
723 }
724
725 int median = 0;
726 int std = 0;
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000727 float poor_fraction = 0;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000728 // Get delay-logging values from Audio Processing Module.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000729 if (_shared->audio_processing()->echo_cancellation()->GetDelayMetrics(
Jelena Marusic0d266052015-05-04 14:15:32 +0200730 &median, &std, &poor_fraction)) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000731 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000732 "GetEcDelayMetrics(), AudioProcessingModule delay-logging "
733 "error");
734 return -1;
735 }
736
737 // EC delay-logging metrics
738 delay_median = median;
739 delay_std = std;
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +0000740 fraction_poor_delays = poor_fraction;
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000741
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000742 return 0;
743#else
henrik.lundinae0b3332016-10-10 07:24:53 -0700744#error "This is deprecated"
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000745 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200746 "SetEcStatus() EC is not supported");
bjornv@webrtc.org3765bd22011-10-17 08:49:23 +0000747 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000748#endif
749}
750
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000751int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000752 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000753 "StartDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000754 if (!_shared->statistics().Initialized()) {
755 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000756 return -1;
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000757 }
758
ivocd66b44d2016-01-15 03:06:36 -0800759 return _shared->audio_processing()->StartDebugRecording(fileNameUTF8, -1);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000760}
761
henrikg@webrtc.org863b5362013-12-06 16:05:17 +0000762int VoEAudioProcessingImpl::StartDebugRecording(FILE* file_handle) {
763 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
764 "StartDebugRecording()");
765 if (!_shared->statistics().Initialized()) {
766 _shared->SetLastError(VE_NOT_INITED, kTraceError);
767 return -1;
768 }
769
ivocd66b44d2016-01-15 03:06:36 -0800770 return _shared->audio_processing()->StartDebugRecording(file_handle, -1);
henrikg@webrtc.org863b5362013-12-06 16:05:17 +0000771}
772
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000773int VoEAudioProcessingImpl::StopDebugRecording() {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000774 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000775 "StopDebugRecording()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000776 if (!_shared->statistics().Initialized()) {
777 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000778 return -1;
779 }
780
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000781 return _shared->audio_processing()->StopDebugRecording();
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000782}
783
784int VoEAudioProcessingImpl::SetTypingDetectionStatus(bool enable) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000785 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000786 "SetTypingDetectionStatus()");
andrew@webrtc.org0851df82013-06-19 17:03:47 +0000787#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
788 NOT_SUPPORTED(_shared->statistics());
789#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000790 if (!_shared->statistics().Initialized()) {
791 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000792 return -1;
793 }
794
795 // Just use the VAD state to determine if we should enable typing detection
796 // or not
797
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000798 if (_shared->audio_processing()->voice_detection()->Enable(enable)) {
799 _shared->SetLastError(VE_APM_ERROR, kTraceWarning,
Jelena Marusic0d266052015-05-04 14:15:32 +0200800 "SetTypingDetectionStatus() failed to set VAD state");
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000801 return -1;
802 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000803 if (_shared->audio_processing()->voice_detection()->set_likelihood(
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000804 VoiceDetection::kVeryLowLikelihood)) {
Jelena Marusic0d266052015-05-04 14:15:32 +0200805 _shared->SetLastError(
806 VE_APM_ERROR, kTraceWarning,
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000807 "SetTypingDetectionStatus() failed to set VAD likelihood to low");
808 return -1;
809 }
810
811 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000812#endif
813}
814
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000815int VoEAudioProcessingImpl::GetTypingDetectionStatus(bool& enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000816 if (!_shared->statistics().Initialized()) {
817 _shared->SetLastError(VE_NOT_INITED, kTraceError);
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000818 return -1;
819 }
820 // Just use the VAD state to determine if we should enable typing
821 // detection or not
niklase@google.com470e71d2011-07-07 08:21:25 +0000822
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000823 enabled = _shared->audio_processing()->voice_detection()->is_enabled();
niklase@google.com470e71d2011-07-07 08:21:25 +0000824
andrew@webrtc.org8b111eb2012-03-06 19:50:12 +0000825 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000826}
827
Jelena Marusic0d266052015-05-04 14:15:32 +0200828int VoEAudioProcessingImpl::TimeSinceLastTyping(int& seconds) {
andrew@webrtc.org0851df82013-06-19 17:03:47 +0000829#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
830 NOT_SUPPORTED(_shared->statistics());
831#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000832 if (!_shared->statistics().Initialized()) {
833 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +0000834 return -1;
835 }
836 // Check if typing detection is enabled
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000837 bool enabled = _shared->audio_processing()->voice_detection()->is_enabled();
Jelena Marusic0d266052015-05-04 14:15:32 +0200838 if (enabled) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000839 _shared->transmit_mixer()->TimeSinceLastTyping(seconds);
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +0000840 return 0;
Jelena Marusic0d266052015-05-04 14:15:32 +0200841 } else {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000842 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
Jelena Marusic0d266052015-05-04 14:15:32 +0200843 "SetTypingDetectionStatus is not enabled");
844 return -1;
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +0000845 }
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +0000846#endif
niklas.enbom@webrtc.org3dc88652012-03-30 09:53:54 +0000847}
848
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +0000849int VoEAudioProcessingImpl::SetTypingDetectionParameters(int timeWindow,
850 int costPerTyping,
851 int reportingThreshold,
niklas.enbom@webrtc.orgf6edfef2012-05-09 13:16:12 +0000852 int penaltyDecay,
853 int typeEventDelay) {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000854 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +0000855 "SetTypingDetectionParameters()");
andrew@webrtc.org0851df82013-06-19 17:03:47 +0000856#if !defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION)
857 NOT_SUPPORTED(_shared->statistics());
858#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000859 if (!_shared->statistics().Initialized()) {
860 _shared->statistics().SetLastError(VE_NOT_INITED, kTraceError);
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +0000861 return -1;
862 }
Jelena Marusic0d266052015-05-04 14:15:32 +0200863 return (_shared->transmit_mixer()->SetTypingDetectionParameters(
864 timeWindow, costPerTyping, reportingThreshold, penaltyDecay,
865 typeEventDelay));
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +0000866#endif
niklas.enbom@webrtc.org06e722a2012-04-04 07:44:27 +0000867}
868
andrew@webrtc.org02d71742012-04-24 19:47:00 +0000869void VoEAudioProcessingImpl::EnableStereoChannelSwapping(bool enable) {
andrew@webrtc.org02d71742012-04-24 19:47:00 +0000870 _shared->transmit_mixer()->EnableStereoChannelSwapping(enable);
871}
872
873bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
andrew@webrtc.org02d71742012-04-24 19:47:00 +0000874 return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
875}
876
niklase@google.com470e71d2011-07-07 08:21:25 +0000877#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
878
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000879} // namespace webrtc