blob: a2d5c44b107ab8eb65b38972afb1be6739f1d2bf [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +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_volume_control_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000013#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
14#include "webrtc/system_wrappers/interface/trace.h"
15#include "webrtc/voice_engine/channel.h"
16#include "webrtc/voice_engine/include/voe_errors.h"
17#include "webrtc/voice_engine/output_mixer.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
21namespace webrtc {
22
23VoEVolumeControl* VoEVolumeControl::GetInterface(VoiceEngine* voiceEngine)
24{
25#ifndef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API
26 return NULL;
27#else
28 if (NULL == voiceEngine)
29 {
30 return NULL;
31 }
tommi@webrtc.org0989fb72013-02-15 15:07:32 +000032 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
tommi@webrtc.orga990e122012-04-26 15:28:22 +000033 s->AddRef();
34 return s;
niklase@google.com470e71d2011-07-07 08:21:25 +000035#endif
36}
37
38#ifdef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API
39
tommi@webrtc.org851becd2012-04-04 14:57:19 +000040VoEVolumeControlImpl::VoEVolumeControlImpl(voe::SharedData* shared)
41 : _shared(shared)
niklase@google.com470e71d2011-07-07 08:21:25 +000042{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000043 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000044 "VoEVolumeControlImpl::VoEVolumeControlImpl() - ctor");
45}
46
47VoEVolumeControlImpl::~VoEVolumeControlImpl()
48{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000049 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000050 "VoEVolumeControlImpl::~VoEVolumeControlImpl() - dtor");
51}
52
niklase@google.com470e71d2011-07-07 08:21:25 +000053int VoEVolumeControlImpl::SetSpeakerVolume(unsigned int volume)
54{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000055 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000056 "SetSpeakerVolume(volume=%u)", volume);
sjlee@webrtc.org4b425082012-09-10 17:58:21 +000057 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +000058
tommi@webrtc.org851becd2012-04-04 14:57:19 +000059 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +000060 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000061 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +000062 return -1;
63 }
64 if (volume > kMaxVolumeLevel)
65 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000066 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +000067 "SetSpeakerVolume() invalid argument");
68 return -1;
69 }
70
pbos@webrtc.org6141e132013-04-09 10:09:10 +000071 uint32_t maxVol(0);
72 uint32_t spkrVol(0);
niklase@google.com470e71d2011-07-07 08:21:25 +000073
74 // scale: [0,kMaxVolumeLevel] -> [0,MaxSpeakerVolume]
tommi@webrtc.org851becd2012-04-04 14:57:19 +000075 if (_shared->audio_device()->MaxSpeakerVolume(&maxVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +000076 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000077 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +000078 "SetSpeakerVolume() failed to get max volume");
79 return -1;
80 }
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +000081 // Round the value and avoid floating computation.
pbos@webrtc.org6141e132013-04-09 10:09:10 +000082 spkrVol = (uint32_t)((volume * maxVol +
niklase@google.com470e71d2011-07-07 08:21:25 +000083 (int)(kMaxVolumeLevel / 2)) / (kMaxVolumeLevel));
84
85 // set the actual volume using the audio mixer
tommi@webrtc.org851becd2012-04-04 14:57:19 +000086 if (_shared->audio_device()->SetSpeakerVolume(spkrVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +000087 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000088 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +000089 "SetSpeakerVolume() failed to set speaker volume");
90 return -1;
91 }
92 return 0;
93}
94
95int VoEVolumeControlImpl::GetSpeakerVolume(unsigned int& volume)
96{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000097 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000098 "GetSpeakerVolume()");
sjlee@webrtc.org4b425082012-09-10 17:58:21 +000099 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000100
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000101 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000102 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000103 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000104 return -1;
105 }
106
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000107 uint32_t spkrVol(0);
108 uint32_t maxVol(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000109
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000110 if (_shared->audio_device()->SpeakerVolume(&spkrVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000111 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000112 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000113 "GetSpeakerVolume() unable to get speaker volume");
114 return -1;
115 }
116
117 // scale: [0, MaxSpeakerVolume] -> [0, kMaxVolumeLevel]
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000118 if (_shared->audio_device()->MaxSpeakerVolume(&maxVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000119 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000120 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000121 "GetSpeakerVolume() unable to get max speaker volume");
122 return -1;
123 }
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000124 // Round the value and avoid floating computation.
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000125 volume = (uint32_t) ((spkrVol * kMaxVolumeLevel +
niklase@google.com470e71d2011-07-07 08:21:25 +0000126 (int)(maxVol / 2)) / (maxVol));
127
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000128 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
129 VoEId(_shared->instance_id(), -1),
130 "GetSpeakerVolume() => volume=%d", volume);
niklase@google.com470e71d2011-07-07 08:21:25 +0000131 return 0;
132}
133
134int VoEVolumeControlImpl::SetSystemOutputMute(bool enable)
135{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000136 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000137 "GetSystemOutputMute(enabled=%d)", enable);
138
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000139 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000140 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000141 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000142 return -1;
143 }
144
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000145 if (_shared->audio_device()->SetSpeakerMute(enable) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000146 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000147 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000148 "SpeakerMute() unable to Set speaker mute");
149 return -1;
150 }
151
152 return 0;
153}
154
155int VoEVolumeControlImpl::GetSystemOutputMute(bool& enabled)
156{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000157 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000158 "GetSystemOutputMute(enabled=?)");
159
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000160 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000161 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000162 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000163 return -1;
164 }
165
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000166 if (_shared->audio_device()->SpeakerMute(&enabled) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000167 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000168 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000169 "SpeakerMute() unable to get speaker mute state");
170 return -1;
171 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000172 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
173 VoEId(_shared->instance_id(), -1),
174 "GetSystemOutputMute() => %d", enabled);
niklase@google.com470e71d2011-07-07 08:21:25 +0000175 return 0;
176}
177
178int VoEVolumeControlImpl::SetMicVolume(unsigned int volume)
179{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000180 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000181 "SetMicVolume(volume=%u)", volume);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000182 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000183 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000184
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000185 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000186 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000187 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000188 return -1;
189 }
190 if (volume > kMaxVolumeLevel)
191 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000192 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000193 "SetMicVolume() invalid argument");
194 return -1;
195 }
196
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000197 uint32_t maxVol(0);
198 uint32_t micVol(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000199
200 // scale: [0, kMaxVolumeLevel] -> [0,MaxMicrophoneVolume]
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000201 if (_shared->audio_device()->MaxMicrophoneVolume(&maxVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000202 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000203 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000204 "SetMicVolume() failed to get max volume");
205 return -1;
206 }
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000207
208 if (volume == kMaxVolumeLevel) {
209 // On Linux running pulse, users are able to set the volume above 100%
210 // through the volume control panel, where the +100% range is digital
211 // scaling. WebRTC does not support setting the volume above 100%, and
212 // simply ignores changing the volume if the user tries to set it to
213 // |kMaxVolumeLevel| while the current volume is higher than |maxVol|.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000214 if (_shared->audio_device()->MicrophoneVolume(&micVol) != 0) {
215 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000216 "SetMicVolume() unable to get microphone volume");
217 return -1;
218 }
219 if (micVol >= maxVol)
220 return 0;
221 }
222
223 // Round the value and avoid floating point computation.
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000224 micVol = (uint32_t) ((volume * maxVol +
niklase@google.com470e71d2011-07-07 08:21:25 +0000225 (int)(kMaxVolumeLevel / 2)) / (kMaxVolumeLevel));
226
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000227 // set the actual volume using the audio mixer
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000228 if (_shared->audio_device()->SetMicrophoneVolume(micVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000229 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000230 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000231 "SetMicVolume() failed to set mic volume");
232 return -1;
233 }
234 return 0;
235}
236
237int VoEVolumeControlImpl::GetMicVolume(unsigned int& volume)
238{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000239 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000240 "GetMicVolume()");
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000241 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000242 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000243
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000244 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000245 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000246 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000247 return -1;
248 }
249
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000250 uint32_t micVol(0);
251 uint32_t maxVol(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000252
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000253 if (_shared->audio_device()->MicrophoneVolume(&micVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000254 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000255 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000256 "GetMicVolume() unable to get microphone volume");
257 return -1;
258 }
259
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000260 // scale: [0, MaxMicrophoneVolume] -> [0, kMaxVolumeLevel]
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000261 if (_shared->audio_device()->MaxMicrophoneVolume(&maxVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000262 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000263 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000264 "GetMicVolume() unable to get max microphone volume");
265 return -1;
266 }
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000267 if (micVol < maxVol) {
268 // Round the value and avoid floating point calculation.
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000269 volume = (uint32_t) ((micVol * kMaxVolumeLevel +
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000270 (int)(maxVol / 2)) / (maxVol));
271 } else {
272 // Truncate the value to the kMaxVolumeLevel.
273 volume = kMaxVolumeLevel;
274 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000275
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000276 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
277 VoEId(_shared->instance_id(), -1),
278 "GetMicVolume() => volume=%d", volume);
niklase@google.com470e71d2011-07-07 08:21:25 +0000279 return 0;
280}
281
282int VoEVolumeControlImpl::SetInputMute(int channel, bool enable)
283{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000284 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000285 "SetInputMute(channel=%d, enable=%d)", channel, enable);
286
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000287 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000288 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000289 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000290 return -1;
291 }
292 if (channel == -1)
293 {
294 // Mute before demultiplexing <=> affects all channels
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000295 return _shared->transmit_mixer()->SetMute(enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000296 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000297 // Mute after demultiplexing <=> affects one channel only
298 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
299 voe::Channel* channelPtr = ch.channel();
300 if (channelPtr == NULL)
niklase@google.com470e71d2011-07-07 08:21:25 +0000301 {
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000302 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
303 "SetInputMute() failed to locate channel");
304 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000305 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000306 return channelPtr->SetMute(enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000307}
308
309int VoEVolumeControlImpl::GetInputMute(int channel, bool& enabled)
310{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000311 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000312 "GetInputMute(channel=%d)", channel);
313
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000314 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000315 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000316 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000317 return -1;
318 }
319 if (channel == -1)
320 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000321 enabled = _shared->transmit_mixer()->Mute();
niklase@google.com470e71d2011-07-07 08:21:25 +0000322 }
323 else
324 {
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000325 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
326 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000327 if (channelPtr == NULL)
328 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000329 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000330 "SetInputMute() failed to locate channel");
331 return -1;
332 }
333 enabled = channelPtr->Mute();
334 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000335 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
336 VoEId(_shared->instance_id(), -1),
337 "GetInputMute() => enabled = %d", (int)enabled);
niklase@google.com470e71d2011-07-07 08:21:25 +0000338 return 0;
339}
340
341int VoEVolumeControlImpl::SetSystemInputMute(bool enable)
342{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000343 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000344 "SetSystemInputMute(enabled=%d)", enable);
345
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000346 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000347 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000348 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000349 return -1;
350 }
351
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000352 if (_shared->audio_device()->SetMicrophoneMute(enable) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000353 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000354 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000355 "MicrophoneMute() unable to set microphone mute state");
356 return -1;
357 }
358
359 return 0;
360}
361
362int VoEVolumeControlImpl::GetSystemInputMute(bool& enabled)
363{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000364 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000365 "GetSystemInputMute(enabled=?)");
366
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000367 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000368 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000369 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000370 return -1;
371 }
372
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000373 if (_shared->audio_device()->MicrophoneMute(&enabled) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000374 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000375 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000376 "MicrophoneMute() unable to get microphone mute state");
377 return -1;
378 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000379 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
380 VoEId(_shared->instance_id(), -1),
381 "GetSystemInputMute() => %d", enabled);
niklase@google.com470e71d2011-07-07 08:21:25 +0000382 return 0;
383}
384
385int VoEVolumeControlImpl::GetSpeechInputLevel(unsigned int& level)
386{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000387 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000388 "GetSpeechInputLevel()");
zakkhoyt@google.com630504f2011-07-13 20:06:58 +0000389
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000390 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000391 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000392 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000393 return -1;
394 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000395 int8_t currentLevel = _shared->transmit_mixer()->AudioLevel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000396 level = static_cast<unsigned int> (currentLevel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000397 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
398 VoEId(_shared->instance_id(), -1),
399 "GetSpeechInputLevel() => %d", level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000400 return 0;
401}
402
403int VoEVolumeControlImpl::GetSpeechOutputLevel(int channel,
404 unsigned int& level)
405{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000406 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
zakkhoyt@google.com630504f2011-07-13 20:06:58 +0000407 "GetSpeechOutputLevel(channel=%d, level=?)", channel);
zakkhoyt@google.com630504f2011-07-13 20:06:58 +0000408
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000409 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000410 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000411 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000412 return -1;
413 }
414 if (channel == -1)
415 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000416 return _shared->output_mixer()->GetSpeechOutputLevel(
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000417 (uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000418 }
419 else
420 {
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000421 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
422 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000423 if (channelPtr == NULL)
424 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000425 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000426 "GetSpeechOutputLevel() failed to locate channel");
427 return -1;
428 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000429 channelPtr->GetSpeechOutputLevel((uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000430 }
431 return 0;
432}
433
434int VoEVolumeControlImpl::GetSpeechInputLevelFullRange(unsigned int& level)
435{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000436 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000437 "GetSpeechInputLevelFullRange(level=?)");
zakkhoyt@google.com5e266632011-07-15 18:21:34 +0000438
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000439 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000440 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000441 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000442 return -1;
443 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000444 int16_t currentLevel = _shared->transmit_mixer()->
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000445 AudioLevelFullRange();
niklase@google.com470e71d2011-07-07 08:21:25 +0000446 level = static_cast<unsigned int> (currentLevel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000447 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
448 VoEId(_shared->instance_id(), -1),
449 "GetSpeechInputLevelFullRange() => %d", level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000450 return 0;
451}
452
453int VoEVolumeControlImpl::GetSpeechOutputLevelFullRange(int channel,
454 unsigned int& level)
455{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000456 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000457 "GetSpeechOutputLevelFullRange(channel=%d, level=?)", channel);
zakkhoyt@google.com5e266632011-07-15 18:21:34 +0000458
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000459 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000460 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000461 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000462 return -1;
463 }
464 if (channel == -1)
465 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000466 return _shared->output_mixer()->GetSpeechOutputLevelFullRange(
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000467 (uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000468 }
469 else
470 {
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000471 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
472 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000473 if (channelPtr == NULL)
474 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000475 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000476 "GetSpeechOutputLevelFullRange() failed to locate channel");
477 return -1;
478 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000479 channelPtr->GetSpeechOutputLevelFullRange((uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000480 }
481 return 0;
482}
483
484int VoEVolumeControlImpl::SetChannelOutputVolumeScaling(int channel,
485 float scaling)
486{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000487 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000488 "SetChannelOutputVolumeScaling(channel=%d, scaling=%3.2f)",
489 channel, scaling);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000490 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000491 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000492 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000493 return -1;
494 }
495 if (scaling < kMinOutputVolumeScaling ||
496 scaling > kMaxOutputVolumeScaling)
497 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000498 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000499 "SetChannelOutputVolumeScaling() invalid parameter");
500 return -1;
501 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000502 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
503 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000504 if (channelPtr == NULL)
505 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000506 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000507 "SetChannelOutputVolumeScaling() failed to locate channel");
508 return -1;
509 }
510 return channelPtr->SetChannelOutputVolumeScaling(scaling);
511}
512
513int VoEVolumeControlImpl::GetChannelOutputVolumeScaling(int channel,
514 float& scaling)
515{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000516 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000517 "GetChannelOutputVolumeScaling(channel=%d, scaling=?)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000518 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000519 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000520 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000521 return -1;
522 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000523 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
524 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000525 if (channelPtr == NULL)
526 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000527 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000528 "GetChannelOutputVolumeScaling() failed to locate channel");
529 return -1;
530 }
531 return channelPtr->GetChannelOutputVolumeScaling(scaling);
532}
533
534int VoEVolumeControlImpl::SetOutputVolumePan(int channel,
535 float left,
536 float right)
537{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000538 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000539 "SetOutputVolumePan(channel=%d, left=%2.1f, right=%2.1f)",
540 channel, left, right);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000541 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000542 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000543
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000544 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000545 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000546 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000547 return -1;
548 }
549
550 bool available(false);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000551 _shared->audio_device()->StereoPlayoutIsAvailable(&available);
niklase@google.com470e71d2011-07-07 08:21:25 +0000552 if (!available)
553 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000554 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000555 "SetOutputVolumePan() stereo playout not supported");
556 return -1;
557 }
558 if ((left < kMinOutputVolumePanning) ||
559 (left > kMaxOutputVolumePanning) ||
560 (right < kMinOutputVolumePanning) ||
561 (right > kMaxOutputVolumePanning))
562 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000563 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000564 "SetOutputVolumePan() invalid parameter");
565 return -1;
566 }
567
568 if (channel == -1)
569 {
570 // Master balance (affectes the signal after output mixing)
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000571 return _shared->output_mixer()->SetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000572 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000573 // Per-channel balance (affects the signal before output mixing)
574 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
575 voe::Channel* channelPtr = ch.channel();
576 if (channelPtr == NULL)
niklase@google.com470e71d2011-07-07 08:21:25 +0000577 {
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000578 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
579 "SetOutputVolumePan() failed to locate channel");
580 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000581 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000582 return channelPtr->SetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000583}
584
585int VoEVolumeControlImpl::GetOutputVolumePan(int channel,
586 float& left,
587 float& right)
588{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000589 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000590 "GetOutputVolumePan(channel=%d, left=?, right=?)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000591 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000592 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000593
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000594 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000595 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000596 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000597 return -1;
598 }
599
600 bool available(false);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000601 _shared->audio_device()->StereoPlayoutIsAvailable(&available);
niklase@google.com470e71d2011-07-07 08:21:25 +0000602 if (!available)
603 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000604 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000605 "GetOutputVolumePan() stereo playout not supported");
606 return -1;
607 }
608
609 if (channel == -1)
610 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000611 return _shared->output_mixer()->GetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000612 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000613 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
614 voe::Channel* channelPtr = ch.channel();
615 if (channelPtr == NULL)
niklase@google.com470e71d2011-07-07 08:21:25 +0000616 {
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000617 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
618 "GetOutputVolumePan() failed to locate channel");
619 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000620 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000621 return channelPtr->GetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000622}
623
624#endif // #ifdef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API
625
626} // namespace webrtc