blob: f27c4ffca1992e062a8d83cdfd50b65fdc9d036b [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);
niklase@google.com470e71d2011-07-07 08:21:25 +000057
tommi@webrtc.org851becd2012-04-04 14:57:19 +000058 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +000059 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000060 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +000061 return -1;
62 }
63 if (volume > kMaxVolumeLevel)
64 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000065 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +000066 "SetSpeakerVolume() invalid argument");
67 return -1;
68 }
69
pbos@webrtc.org6141e132013-04-09 10:09:10 +000070 uint32_t maxVol(0);
71 uint32_t spkrVol(0);
niklase@google.com470e71d2011-07-07 08:21:25 +000072
73 // scale: [0,kMaxVolumeLevel] -> [0,MaxSpeakerVolume]
tommi@webrtc.org851becd2012-04-04 14:57:19 +000074 if (_shared->audio_device()->MaxSpeakerVolume(&maxVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +000075 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000076 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +000077 "SetSpeakerVolume() failed to get max volume");
78 return -1;
79 }
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +000080 // Round the value and avoid floating computation.
pbos@webrtc.org6141e132013-04-09 10:09:10 +000081 spkrVol = (uint32_t)((volume * maxVol +
niklase@google.com470e71d2011-07-07 08:21:25 +000082 (int)(kMaxVolumeLevel / 2)) / (kMaxVolumeLevel));
83
84 // set the actual volume using the audio mixer
tommi@webrtc.org851becd2012-04-04 14:57:19 +000085 if (_shared->audio_device()->SetSpeakerVolume(spkrVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +000086 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000087 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +000088 "SetSpeakerVolume() failed to set speaker volume");
89 return -1;
90 }
91 return 0;
92}
93
94int VoEVolumeControlImpl::GetSpeakerVolume(unsigned int& volume)
95{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000096 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000097 "GetSpeakerVolume()");
niklase@google.com470e71d2011-07-07 08:21:25 +000098
tommi@webrtc.org851becd2012-04-04 14:57:19 +000099 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000100 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000101 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000102 return -1;
103 }
104
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000105 uint32_t spkrVol(0);
106 uint32_t maxVol(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000107
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000108 if (_shared->audio_device()->SpeakerVolume(&spkrVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000109 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000110 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000111 "GetSpeakerVolume() unable to get speaker volume");
112 return -1;
113 }
114
115 // scale: [0, MaxSpeakerVolume] -> [0, kMaxVolumeLevel]
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000116 if (_shared->audio_device()->MaxSpeakerVolume(&maxVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000117 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000118 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000119 "GetSpeakerVolume() unable to get max speaker volume");
120 return -1;
121 }
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000122 // Round the value and avoid floating computation.
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000123 volume = (uint32_t) ((spkrVol * kMaxVolumeLevel +
niklase@google.com470e71d2011-07-07 08:21:25 +0000124 (int)(maxVol / 2)) / (maxVol));
125
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000126 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
127 VoEId(_shared->instance_id(), -1),
128 "GetSpeakerVolume() => volume=%d", volume);
niklase@google.com470e71d2011-07-07 08:21:25 +0000129 return 0;
130}
131
niklase@google.com470e71d2011-07-07 08:21:25 +0000132int VoEVolumeControlImpl::SetMicVolume(unsigned int volume)
133{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000134 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000135 "SetMicVolume(volume=%u)", volume);
niklase@google.com470e71d2011-07-07 08:21:25 +0000136
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000137 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000138 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000139 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000140 return -1;
141 }
142 if (volume > kMaxVolumeLevel)
143 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000144 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000145 "SetMicVolume() invalid argument");
146 return -1;
147 }
148
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000149 uint32_t maxVol(0);
150 uint32_t micVol(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000151
152 // scale: [0, kMaxVolumeLevel] -> [0,MaxMicrophoneVolume]
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000153 if (_shared->audio_device()->MaxMicrophoneVolume(&maxVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000154 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000155 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000156 "SetMicVolume() failed to get max volume");
157 return -1;
158 }
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000159
160 if (volume == kMaxVolumeLevel) {
161 // On Linux running pulse, users are able to set the volume above 100%
162 // through the volume control panel, where the +100% range is digital
163 // scaling. WebRTC does not support setting the volume above 100%, and
164 // simply ignores changing the volume if the user tries to set it to
165 // |kMaxVolumeLevel| while the current volume is higher than |maxVol|.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000166 if (_shared->audio_device()->MicrophoneVolume(&micVol) != 0) {
167 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000168 "SetMicVolume() unable to get microphone volume");
169 return -1;
170 }
171 if (micVol >= maxVol)
172 return 0;
173 }
174
175 // Round the value and avoid floating point computation.
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000176 micVol = (uint32_t) ((volume * maxVol +
niklase@google.com470e71d2011-07-07 08:21:25 +0000177 (int)(kMaxVolumeLevel / 2)) / (kMaxVolumeLevel));
178
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000179 // set the actual volume using the audio mixer
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000180 if (_shared->audio_device()->SetMicrophoneVolume(micVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000181 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000182 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000183 "SetMicVolume() failed to set mic volume");
184 return -1;
185 }
186 return 0;
187}
188
189int VoEVolumeControlImpl::GetMicVolume(unsigned int& volume)
190{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000191 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000192 "GetMicVolume()");
niklase@google.com470e71d2011-07-07 08:21:25 +0000193
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000194 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000195 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000196 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000197 return -1;
198 }
199
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000200 uint32_t micVol(0);
201 uint32_t maxVol(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000202
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000203 if (_shared->audio_device()->MicrophoneVolume(&micVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000204 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000205 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000206 "GetMicVolume() unable to get microphone volume");
207 return -1;
208 }
209
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000210 // scale: [0, MaxMicrophoneVolume] -> [0, kMaxVolumeLevel]
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000211 if (_shared->audio_device()->MaxMicrophoneVolume(&maxVol) != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000212 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000213 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000214 "GetMicVolume() unable to get max microphone volume");
215 return -1;
216 }
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000217 if (micVol < maxVol) {
218 // Round the value and avoid floating point calculation.
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000219 volume = (uint32_t) ((micVol * kMaxVolumeLevel +
xians@webrtc.org3ab6dda2012-02-16 18:15:54 +0000220 (int)(maxVol / 2)) / (maxVol));
221 } else {
222 // Truncate the value to the kMaxVolumeLevel.
223 volume = kMaxVolumeLevel;
224 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000225
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000226 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
227 VoEId(_shared->instance_id(), -1),
228 "GetMicVolume() => volume=%d", volume);
niklase@google.com470e71d2011-07-07 08:21:25 +0000229 return 0;
230}
231
232int VoEVolumeControlImpl::SetInputMute(int channel, bool enable)
233{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000234 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000235 "SetInputMute(channel=%d, enable=%d)", channel, enable);
236
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000237 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000238 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000239 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000240 return -1;
241 }
242 if (channel == -1)
243 {
244 // Mute before demultiplexing <=> affects all channels
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000245 return _shared->transmit_mixer()->SetMute(enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000246 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000247 // Mute after demultiplexing <=> affects one channel only
248 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
249 voe::Channel* channelPtr = ch.channel();
250 if (channelPtr == NULL)
niklase@google.com470e71d2011-07-07 08:21:25 +0000251 {
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000252 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
253 "SetInputMute() failed to locate channel");
254 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000255 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000256 return channelPtr->SetMute(enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000257}
258
259int VoEVolumeControlImpl::GetInputMute(int channel, bool& enabled)
260{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000261 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000262 "GetInputMute(channel=%d)", channel);
263
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000264 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000265 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000266 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000267 return -1;
268 }
269 if (channel == -1)
270 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000271 enabled = _shared->transmit_mixer()->Mute();
niklase@google.com470e71d2011-07-07 08:21:25 +0000272 }
273 else
274 {
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000275 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
276 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000277 if (channelPtr == NULL)
278 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000279 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000280 "SetInputMute() failed to locate channel");
281 return -1;
282 }
283 enabled = channelPtr->Mute();
284 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000285 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
286 VoEId(_shared->instance_id(), -1),
287 "GetInputMute() => enabled = %d", (int)enabled);
niklase@google.com470e71d2011-07-07 08:21:25 +0000288 return 0;
289}
290
niklase@google.com470e71d2011-07-07 08:21:25 +0000291int VoEVolumeControlImpl::GetSpeechInputLevel(unsigned int& level)
292{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000293 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000294 "GetSpeechInputLevel()");
zakkhoyt@google.com630504f2011-07-13 20:06:58 +0000295
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000296 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000297 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000298 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000299 return -1;
300 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000301 int8_t currentLevel = _shared->transmit_mixer()->AudioLevel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000302 level = static_cast<unsigned int> (currentLevel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000303 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
304 VoEId(_shared->instance_id(), -1),
305 "GetSpeechInputLevel() => %d", level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000306 return 0;
307}
308
309int VoEVolumeControlImpl::GetSpeechOutputLevel(int channel,
310 unsigned int& level)
311{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000312 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
zakkhoyt@google.com630504f2011-07-13 20:06:58 +0000313 "GetSpeechOutputLevel(channel=%d, level=?)", channel);
henrika@webrtc.orgf383a1b2014-05-14 11:51:45 +0000314
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000315 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000316 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000317 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000318 return -1;
319 }
320 if (channel == -1)
321 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000322 return _shared->output_mixer()->GetSpeechOutputLevel(
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000323 (uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000324 }
325 else
326 {
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000327 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
328 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000329 if (channelPtr == NULL)
330 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000331 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000332 "GetSpeechOutputLevel() failed to locate channel");
333 return -1;
334 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000335 channelPtr->GetSpeechOutputLevel((uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000336 }
337 return 0;
338}
339
340int VoEVolumeControlImpl::GetSpeechInputLevelFullRange(unsigned int& level)
341{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000342 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 "GetSpeechInputLevelFullRange(level=?)");
zakkhoyt@google.com5e266632011-07-15 18:21:34 +0000344
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000345 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000347 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000348 return -1;
349 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000350 int16_t currentLevel = _shared->transmit_mixer()->
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000351 AudioLevelFullRange();
niklase@google.com470e71d2011-07-07 08:21:25 +0000352 level = static_cast<unsigned int> (currentLevel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000353 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
354 VoEId(_shared->instance_id(), -1),
355 "GetSpeechInputLevelFullRange() => %d", level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000356 return 0;
357}
358
359int VoEVolumeControlImpl::GetSpeechOutputLevelFullRange(int channel,
360 unsigned int& level)
361{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000362 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000363 "GetSpeechOutputLevelFullRange(channel=%d, level=?)", channel);
zakkhoyt@google.com5e266632011-07-15 18:21:34 +0000364
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000365 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000366 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000367 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000368 return -1;
369 }
370 if (channel == -1)
371 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000372 return _shared->output_mixer()->GetSpeechOutputLevelFullRange(
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000373 (uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000374 }
375 else
376 {
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000377 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
378 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000379 if (channelPtr == NULL)
380 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000381 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000382 "GetSpeechOutputLevelFullRange() failed to locate channel");
383 return -1;
384 }
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000385 channelPtr->GetSpeechOutputLevelFullRange((uint32_t&)level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000386 }
387 return 0;
388}
389
390int VoEVolumeControlImpl::SetChannelOutputVolumeScaling(int channel,
391 float scaling)
392{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000393 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000394 "SetChannelOutputVolumeScaling(channel=%d, scaling=%3.2f)",
395 channel, scaling);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000396 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000397 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000398 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000399 return -1;
400 }
401 if (scaling < kMinOutputVolumeScaling ||
402 scaling > kMaxOutputVolumeScaling)
403 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000404 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000405 "SetChannelOutputVolumeScaling() invalid parameter");
406 return -1;
407 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000408 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
409 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000410 if (channelPtr == NULL)
411 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000412 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000413 "SetChannelOutputVolumeScaling() failed to locate channel");
414 return -1;
415 }
416 return channelPtr->SetChannelOutputVolumeScaling(scaling);
417}
418
419int VoEVolumeControlImpl::GetChannelOutputVolumeScaling(int channel,
420 float& scaling)
421{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000422 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000423 "GetChannelOutputVolumeScaling(channel=%d, scaling=?)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000424 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000425 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000426 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000427 return -1;
428 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000429 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
430 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000431 if (channelPtr == NULL)
432 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000433 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000434 "GetChannelOutputVolumeScaling() failed to locate channel");
435 return -1;
436 }
437 return channelPtr->GetChannelOutputVolumeScaling(scaling);
438}
439
440int VoEVolumeControlImpl::SetOutputVolumePan(int channel,
441 float left,
442 float right)
443{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000444 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000445 "SetOutputVolumePan(channel=%d, left=%2.1f, right=%2.1f)",
446 channel, left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000447
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000448 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000449 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000450 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000451 return -1;
452 }
453
454 bool available(false);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000455 _shared->audio_device()->StereoPlayoutIsAvailable(&available);
niklase@google.com470e71d2011-07-07 08:21:25 +0000456 if (!available)
457 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000458 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000459 "SetOutputVolumePan() stereo playout not supported");
460 return -1;
461 }
462 if ((left < kMinOutputVolumePanning) ||
463 (left > kMaxOutputVolumePanning) ||
464 (right < kMinOutputVolumePanning) ||
465 (right > kMaxOutputVolumePanning))
466 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000467 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000468 "SetOutputVolumePan() invalid parameter");
469 return -1;
470 }
471
472 if (channel == -1)
473 {
474 // Master balance (affectes the signal after output mixing)
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000475 return _shared->output_mixer()->SetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000476 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000477 // Per-channel balance (affects the signal before output mixing)
478 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
479 voe::Channel* channelPtr = ch.channel();
480 if (channelPtr == NULL)
niklase@google.com470e71d2011-07-07 08:21:25 +0000481 {
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000482 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
483 "SetOutputVolumePan() failed to locate channel");
484 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000485 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000486 return channelPtr->SetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000487}
488
489int VoEVolumeControlImpl::GetOutputVolumePan(int channel,
490 float& left,
491 float& right)
492{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000493 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000494 "GetOutputVolumePan(channel=%d, left=?, right=?)", channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000495
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000496 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000497 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000498 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000499 return -1;
500 }
501
502 bool available(false);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000503 _shared->audio_device()->StereoPlayoutIsAvailable(&available);
niklase@google.com470e71d2011-07-07 08:21:25 +0000504 if (!available)
505 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000506 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000507 "GetOutputVolumePan() stereo playout not supported");
508 return -1;
509 }
510
511 if (channel == -1)
512 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000513 return _shared->output_mixer()->GetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000514 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000515 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
516 voe::Channel* channelPtr = ch.channel();
517 if (channelPtr == NULL)
niklase@google.com470e71d2011-07-07 08:21:25 +0000518 {
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000519 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
520 "GetOutputVolumePan() failed to locate channel");
521 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000522 }
pbos@webrtc.org0e65fda2014-03-21 10:26:42 +0000523 return channelPtr->GetOutputVolumePan(left, right);
niklase@google.com470e71d2011-07-07 08:21:25 +0000524}
525
526#endif // #ifdef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API
527
528} // namespace webrtc