blob: f0d165217a2046a0080edfc4fb78be6dc5437e7f [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.orga990e122012-04-26 15:28:22 +000032 VoiceEngineImpl* s = reinterpret_cast<VoiceEngineImpl*>(voiceEngine);
33 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
71 WebRtc_UWord32 maxVol(0);
72 WebRtc_UWord32 spkrVol(0);
73
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.
niklase@google.com470e71d2011-07-07 08:21:25 +000082 spkrVol = (WebRtc_UWord32)((volume * maxVol +
83 (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
107 WebRtc_UWord32 spkrVol(0);
108 WebRtc_UWord32 maxVol(0);
109
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.
niklase@google.com470e71d2011-07-07 08:21:25 +0000125 volume = (WebRtc_UWord32) ((spkrVol * kMaxVolumeLevel +
126 (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
197 WebRtc_UWord32 maxVol(0);
198 WebRtc_UWord32 micVol(0);
199
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.
niklase@google.com470e71d2011-07-07 08:21:25 +0000224 micVol = (WebRtc_UWord32) ((volume * maxVol +
225 (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
250 WebRtc_UWord32 micVol(0);
251 WebRtc_UWord32 maxVol(0);
252
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.
269 volume = (WebRtc_UWord32) ((micVol * kMaxVolumeLevel +
270 (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 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000399 WebRtc_Word8 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(
421 (WebRtc_UWord32&)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 }
433 channelPtr->GetSpeechOutputLevel((WebRtc_UWord32&)level);
434 }
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 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000448 WebRtc_Word16 currentLevel = _shared->transmit_mixer()->
449 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(
niklase@google.com470e71d2011-07-07 08:21:25 +0000471 (WebRtc_UWord32&)level);
472 }
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 }
483 channelPtr->GetSpeechOutputLevelFullRange((WebRtc_UWord32&)level);
484 }
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);
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000494 IPHONE_NOT_SUPPORTED(_shared->statistics());
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000495 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000496 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000497 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000498 return -1;
499 }
500 if (scaling < kMinOutputVolumeScaling ||
501 scaling > kMaxOutputVolumeScaling)
502 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000503 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000504 "SetChannelOutputVolumeScaling() invalid parameter");
505 return -1;
506 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000507 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000508 voe::Channel* channelPtr = sc.ChannelPtr();
509 if (channelPtr == NULL)
510 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000511 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000512 "SetChannelOutputVolumeScaling() failed to locate channel");
513 return -1;
514 }
515 return channelPtr->SetChannelOutputVolumeScaling(scaling);
516}
517
518int VoEVolumeControlImpl::GetChannelOutputVolumeScaling(int channel,
519 float& scaling)
520{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000521 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000522 "GetChannelOutputVolumeScaling(channel=%d, scaling=?)", channel);
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000523 IPHONE_NOT_SUPPORTED(_shared->statistics());
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000524 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000525 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000526 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000527 return -1;
528 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000529 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000530 voe::Channel* channelPtr = sc.ChannelPtr();
531 if (channelPtr == NULL)
532 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000533 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000534 "GetChannelOutputVolumeScaling() failed to locate channel");
535 return -1;
536 }
537 return channelPtr->GetChannelOutputVolumeScaling(scaling);
538}
539
540int VoEVolumeControlImpl::SetOutputVolumePan(int channel,
541 float left,
542 float right)
543{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000544 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000545 "SetOutputVolumePan(channel=%d, left=%2.1f, right=%2.1f)",
546 channel, left, right);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000547 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000548 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000549
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000550 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000551 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000552 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000553 return -1;
554 }
555
556 bool available(false);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000557 _shared->audio_device()->StereoPlayoutIsAvailable(&available);
niklase@google.com470e71d2011-07-07 08:21:25 +0000558 if (!available)
559 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000560 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000561 "SetOutputVolumePan() stereo playout not supported");
562 return -1;
563 }
564 if ((left < kMinOutputVolumePanning) ||
565 (left > kMaxOutputVolumePanning) ||
566 (right < kMinOutputVolumePanning) ||
567 (right > kMaxOutputVolumePanning))
568 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000569 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000570 "SetOutputVolumePan() invalid parameter");
571 return -1;
572 }
573
574 if (channel == -1)
575 {
576 // Master balance (affectes the signal after output mixing)
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000577 return _shared->output_mixer()->SetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000578 }
579 else
580 {
581 // Per-channel balance (affects the signal before output mixing)
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000582 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000583 voe::Channel* channelPtr = sc.ChannelPtr();
584 if (channelPtr == NULL)
585 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000586 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000587 "SetOutputVolumePan() failed to locate channel");
588 return -1;
589 }
590 return channelPtr->SetOutputVolumePan(left, right);
591 }
592 return 0;
593}
594
595int VoEVolumeControlImpl::GetOutputVolumePan(int channel,
596 float& left,
597 float& right)
598{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000599 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000600 "GetOutputVolumePan(channel=%d, left=?, right=?)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000601 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000602 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000603
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000604 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000605 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000606 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000607 return -1;
608 }
609
610 bool available(false);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000611 _shared->audio_device()->StereoPlayoutIsAvailable(&available);
niklase@google.com470e71d2011-07-07 08:21:25 +0000612 if (!available)
613 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000614 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000615 "GetOutputVolumePan() stereo playout not supported");
616 return -1;
617 }
618
619 if (channel == -1)
620 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000621 return _shared->output_mixer()->GetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000622 }
623 else
624 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000625 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000626 voe::Channel* channelPtr = sc.ChannelPtr();
627 if (channelPtr == NULL)
628 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000629 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000630 "GetOutputVolumePan() failed to locate channel");
631 return -1;
632 }
633 return channelPtr->GetOutputVolumePan(left, right);
634 }
635 return 0;
636}
637
638#endif // #ifdef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API
639
640} // namespace webrtc