blob: 8104242f36b003b9bfa74e50200f310a67ee882c [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
11#include "voe_volume_control_impl.h"
12
13#include "channel.h"
14#include "critical_section_wrapper.h"
15#include "output_mixer.h"
16#include "trace.h"
17#include "transmit_mixer.h"
18#include "voe_errors.h"
19#include "voice_engine_impl.h"
20
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 }
297 else
298 {
299 // Mute after demultiplexing <=> affects one channel only
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000300 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000301 voe::Channel* channelPtr = sc.ChannelPtr();
302 if (channelPtr == NULL)
303 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000304 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000305 "SetInputMute() failed to locate channel");
306 return -1;
307 }
308 return channelPtr->SetMute(enable);
309 }
310 return 0;
311}
312
313int VoEVolumeControlImpl::GetInputMute(int channel, bool& enabled)
314{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000315 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000316 "GetInputMute(channel=%d)", channel);
317
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000318 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000319 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000320 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000321 return -1;
322 }
323 if (channel == -1)
324 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000325 enabled = _shared->transmit_mixer()->Mute();
niklase@google.com470e71d2011-07-07 08:21:25 +0000326 }
327 else
328 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000329 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000330 voe::Channel* channelPtr = sc.ChannelPtr();
331 if (channelPtr == NULL)
332 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000333 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 "SetInputMute() failed to locate channel");
335 return -1;
336 }
337 enabled = channelPtr->Mute();
338 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000339 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
340 VoEId(_shared->instance_id(), -1),
341 "GetInputMute() => enabled = %d", (int)enabled);
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 return 0;
343}
344
345int VoEVolumeControlImpl::SetSystemInputMute(bool enable)
346{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000347 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000348 "SetSystemInputMute(enabled=%d)", enable);
349
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000350 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000351 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000352 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000353 return -1;
354 }
355
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000356 if (_shared->audio_device()->SetMicrophoneMute(enable) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000357 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000358 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000359 "MicrophoneMute() unable to set microphone mute state");
360 return -1;
361 }
362
363 return 0;
364}
365
366int VoEVolumeControlImpl::GetSystemInputMute(bool& enabled)
367{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000368 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000369 "GetSystemInputMute(enabled=?)");
370
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000371 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000372 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000373 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000374 return -1;
375 }
376
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000377 if (_shared->audio_device()->MicrophoneMute(&enabled) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000378 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000379 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000380 "MicrophoneMute() unable to get microphone mute state");
381 return -1;
382 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000383 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
384 VoEId(_shared->instance_id(), -1),
385 "GetSystemInputMute() => %d", enabled);
niklase@google.com470e71d2011-07-07 08:21:25 +0000386 return 0;
387}
388
389int VoEVolumeControlImpl::GetSpeechInputLevel(unsigned int& level)
390{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000391 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000392 "GetSpeechInputLevel()");
zakkhoyt@google.com630504f2011-07-13 20:06:58 +0000393
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000394 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000395 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000396 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000397 return -1;
398 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000399 int8_t currentLevel = _shared->transmit_mixer()->AudioLevel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000400 level = static_cast<unsigned int> (currentLevel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000401 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
402 VoEId(_shared->instance_id(), -1),
403 "GetSpeechInputLevel() => %d", level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000404 return 0;
405}
406
407int VoEVolumeControlImpl::GetSpeechOutputLevel(int channel,
408 unsigned int& level)
409{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000410 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
zakkhoyt@google.com630504f2011-07-13 20:06:58 +0000411 "GetSpeechOutputLevel(channel=%d, level=?)", channel);
zakkhoyt@google.com630504f2011-07-13 20:06:58 +0000412
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000413 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000414 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000415 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000416 return -1;
417 }
418 if (channel == -1)
419 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000420 return _shared->output_mixer()->GetSpeechOutputLevel(
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000421 (uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000422 }
423 else
424 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000425 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000426 voe::Channel* channelPtr = sc.ChannelPtr();
427 if (channelPtr == NULL)
428 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000429 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000430 "GetSpeechOutputLevel() failed to locate channel");
431 return -1;
432 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000433 channelPtr->GetSpeechOutputLevel((uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000434 }
435 return 0;
436}
437
438int VoEVolumeControlImpl::GetSpeechInputLevelFullRange(unsigned int& level)
439{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000440 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000441 "GetSpeechInputLevelFullRange(level=?)");
zakkhoyt@google.com5e266632011-07-15 18:21:34 +0000442
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000443 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000444 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000445 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000446 return -1;
447 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000448 int16_t currentLevel = _shared->transmit_mixer()->
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000449 AudioLevelFullRange();
niklase@google.com470e71d2011-07-07 08:21:25 +0000450 level = static_cast<unsigned int> (currentLevel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000451 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
452 VoEId(_shared->instance_id(), -1),
453 "GetSpeechInputLevelFullRange() => %d", level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000454 return 0;
455}
456
457int VoEVolumeControlImpl::GetSpeechOutputLevelFullRange(int channel,
458 unsigned int& level)
459{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000460 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000461 "GetSpeechOutputLevelFullRange(channel=%d, level=?)", channel);
zakkhoyt@google.com5e266632011-07-15 18:21:34 +0000462
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000463 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000464 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000465 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000466 return -1;
467 }
468 if (channel == -1)
469 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000470 return _shared->output_mixer()->GetSpeechOutputLevelFullRange(
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000471 (uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000472 }
473 else
474 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000475 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000476 voe::Channel* channelPtr = sc.ChannelPtr();
477 if (channelPtr == NULL)
478 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000479 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000480 "GetSpeechOutputLevelFullRange() failed to locate channel");
481 return -1;
482 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000483 channelPtr->GetSpeechOutputLevelFullRange((uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000484 }
485 return 0;
486}
487
488int VoEVolumeControlImpl::SetChannelOutputVolumeScaling(int channel,
489 float scaling)
490{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000491 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000492 "SetChannelOutputVolumeScaling(channel=%d, scaling=%3.2f)",
493 channel, scaling);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000494 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000495 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000496 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000497 return -1;
498 }
499 if (scaling < kMinOutputVolumeScaling ||
500 scaling > kMaxOutputVolumeScaling)
501 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000502 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000503 "SetChannelOutputVolumeScaling() invalid parameter");
504 return -1;
505 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000506 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000507 voe::Channel* channelPtr = sc.ChannelPtr();
508 if (channelPtr == NULL)
509 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000510 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000511 "SetChannelOutputVolumeScaling() failed to locate channel");
512 return -1;
513 }
514 return channelPtr->SetChannelOutputVolumeScaling(scaling);
515}
516
517int VoEVolumeControlImpl::GetChannelOutputVolumeScaling(int channel,
518 float& scaling)
519{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000520 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000521 "GetChannelOutputVolumeScaling(channel=%d, scaling=?)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000522 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000523 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000524 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000525 return -1;
526 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000527 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000528 voe::Channel* channelPtr = sc.ChannelPtr();
529 if (channelPtr == NULL)
530 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000531 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000532 "GetChannelOutputVolumeScaling() failed to locate channel");
533 return -1;
534 }
535 return channelPtr->GetChannelOutputVolumeScaling(scaling);
536}
537
538int VoEVolumeControlImpl::SetOutputVolumePan(int channel,
539 float left,
540 float right)
541{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000542 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000543 "SetOutputVolumePan(channel=%d, left=%2.1f, right=%2.1f)",
544 channel, left, right);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000545 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000546 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000547
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000548 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000549 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000550 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000551 return -1;
552 }
553
554 bool available(false);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000555 _shared->audio_device()->StereoPlayoutIsAvailable(&available);
niklase@google.com470e71d2011-07-07 08:21:25 +0000556 if (!available)
557 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000558 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000559 "SetOutputVolumePan() stereo playout not supported");
560 return -1;
561 }
562 if ((left < kMinOutputVolumePanning) ||
563 (left > kMaxOutputVolumePanning) ||
564 (right < kMinOutputVolumePanning) ||
565 (right > kMaxOutputVolumePanning))
566 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000567 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000568 "SetOutputVolumePan() invalid parameter");
569 return -1;
570 }
571
572 if (channel == -1)
573 {
574 // Master balance (affectes the signal after output mixing)
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000575 return _shared->output_mixer()->SetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000576 }
577 else
578 {
579 // Per-channel balance (affects the signal before output mixing)
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000580 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000581 voe::Channel* channelPtr = sc.ChannelPtr();
582 if (channelPtr == NULL)
583 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000584 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000585 "SetOutputVolumePan() failed to locate channel");
586 return -1;
587 }
588 return channelPtr->SetOutputVolumePan(left, right);
589 }
590 return 0;
591}
592
593int VoEVolumeControlImpl::GetOutputVolumePan(int channel,
594 float& left,
595 float& right)
596{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000597 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000598 "GetOutputVolumePan(channel=%d, left=?, right=?)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000599 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000600 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000601
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000602 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000603 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000604 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000605 return -1;
606 }
607
608 bool available(false);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000609 _shared->audio_device()->StereoPlayoutIsAvailable(&available);
niklase@google.com470e71d2011-07-07 08:21:25 +0000610 if (!available)
611 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000612 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000613 "GetOutputVolumePan() stereo playout not supported");
614 return -1;
615 }
616
617 if (channel == -1)
618 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000619 return _shared->output_mixer()->GetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000620 }
621 else
622 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000623 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000624 voe::Channel* channelPtr = sc.ChannelPtr();
625 if (channelPtr == NULL)
626 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000627 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000628 "GetOutputVolumePan() failed to locate channel");
629 return -1;
630 }
631 return channelPtr->GetOutputVolumePan(left, right);
632 }
633 return 0;
634}
635
636#endif // #ifdef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API
637
638} // namespace webrtc