LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/voice_engine - voe_volume_control_impl.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 233 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
       3             :  *
       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 "webrtc/voice_engine/voe_volume_control_impl.h"
      12             : 
      13             : #include "webrtc/system_wrappers/include/trace.h"
      14             : #include "webrtc/voice_engine/channel.h"
      15             : #include "webrtc/voice_engine/include/voe_errors.h"
      16             : #include "webrtc/voice_engine/output_mixer.h"
      17             : #include "webrtc/voice_engine/transmit_mixer.h"
      18             : #include "webrtc/voice_engine/voice_engine_impl.h"
      19             : 
      20             : namespace webrtc {
      21             : 
      22           0 : VoEVolumeControl* VoEVolumeControl::GetInterface(VoiceEngine* voiceEngine) {
      23           0 :   if (NULL == voiceEngine) {
      24           0 :     return NULL;
      25             :   }
      26           0 :   VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
      27           0 :   s->AddRef();
      28           0 :   return s;
      29             : }
      30             : 
      31           0 : VoEVolumeControlImpl::VoEVolumeControlImpl(voe::SharedData* shared)
      32           0 :     : _shared(shared) {
      33             :   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
      34             :                "VoEVolumeControlImpl::VoEVolumeControlImpl() - ctor");
      35           0 : }
      36             : 
      37           0 : VoEVolumeControlImpl::~VoEVolumeControlImpl() {
      38             :   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
      39             :                "VoEVolumeControlImpl::~VoEVolumeControlImpl() - dtor");
      40           0 : }
      41             : 
      42           0 : int VoEVolumeControlImpl::SetSpeakerVolume(unsigned int volume) {
      43             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
      44             :                "SetSpeakerVolume(volume=%u)", volume);
      45             : 
      46           0 :   if (!_shared->statistics().Initialized()) {
      47           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
      48           0 :     return -1;
      49             :   }
      50           0 :   if (volume > kMaxVolumeLevel) {
      51           0 :     _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
      52           0 :                           "SetSpeakerVolume() invalid argument");
      53           0 :     return -1;
      54             :   }
      55             : 
      56           0 :   uint32_t maxVol(0);
      57           0 :   uint32_t spkrVol(0);
      58             : 
      59             :   // scale: [0,kMaxVolumeLevel] -> [0,MaxSpeakerVolume]
      60           0 :   if (_shared->audio_device()->MaxSpeakerVolume(&maxVol) != 0) {
      61           0 :     _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
      62           0 :                           "SetSpeakerVolume() failed to get max volume");
      63           0 :     return -1;
      64             :   }
      65             :   // Round the value and avoid floating computation.
      66           0 :   spkrVol = (uint32_t)((volume * maxVol + (int)(kMaxVolumeLevel / 2)) /
      67             :                        (kMaxVolumeLevel));
      68             : 
      69             :   // set the actual volume using the audio mixer
      70           0 :   if (_shared->audio_device()->SetSpeakerVolume(spkrVol) != 0) {
      71           0 :     _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
      72           0 :                           "SetSpeakerVolume() failed to set speaker volume");
      73           0 :     return -1;
      74             :   }
      75           0 :   return 0;
      76             : }
      77             : 
      78           0 : int VoEVolumeControlImpl::GetSpeakerVolume(unsigned int& volume) {
      79             : 
      80           0 :   if (!_shared->statistics().Initialized()) {
      81           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
      82           0 :     return -1;
      83             :   }
      84             : 
      85           0 :   uint32_t spkrVol(0);
      86           0 :   uint32_t maxVol(0);
      87             : 
      88           0 :   if (_shared->audio_device()->SpeakerVolume(&spkrVol) != 0) {
      89           0 :     _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
      90           0 :                           "GetSpeakerVolume() unable to get speaker volume");
      91           0 :     return -1;
      92             :   }
      93             : 
      94             :   // scale: [0, MaxSpeakerVolume] -> [0, kMaxVolumeLevel]
      95           0 :   if (_shared->audio_device()->MaxSpeakerVolume(&maxVol) != 0) {
      96           0 :     _shared->SetLastError(
      97             :         VE_GET_MIC_VOL_ERROR, kTraceError,
      98           0 :         "GetSpeakerVolume() unable to get max speaker volume");
      99           0 :     return -1;
     100             :   }
     101             :   // Round the value and avoid floating computation.
     102           0 :   volume =
     103           0 :       (uint32_t)((spkrVol * kMaxVolumeLevel + (int)(maxVol / 2)) / (maxVol));
     104             : 
     105           0 :   return 0;
     106             : }
     107             : 
     108           0 : int VoEVolumeControlImpl::SetMicVolume(unsigned int volume) {
     109             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     110             :                "SetMicVolume(volume=%u)", volume);
     111             : 
     112           0 :   if (!_shared->statistics().Initialized()) {
     113           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     114           0 :     return -1;
     115             :   }
     116           0 :   if (volume > kMaxVolumeLevel) {
     117           0 :     _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
     118           0 :                           "SetMicVolume() invalid argument");
     119           0 :     return -1;
     120             :   }
     121             : 
     122           0 :   uint32_t maxVol(0);
     123           0 :   uint32_t micVol(0);
     124             : 
     125             :   // scale: [0, kMaxVolumeLevel] -> [0,MaxMicrophoneVolume]
     126           0 :   if (_shared->audio_device()->MaxMicrophoneVolume(&maxVol) != 0) {
     127           0 :     _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
     128           0 :                           "SetMicVolume() failed to get max volume");
     129           0 :     return -1;
     130             :   }
     131             : 
     132           0 :   if (volume == kMaxVolumeLevel) {
     133             :     // On Linux running pulse, users are able to set the volume above 100%
     134             :     // through the volume control panel, where the +100% range is digital
     135             :     // scaling. WebRTC does not support setting the volume above 100%, and
     136             :     // simply ignores changing the volume if the user tries to set it to
     137             :     // |kMaxVolumeLevel| while the current volume is higher than |maxVol|.
     138           0 :     if (_shared->audio_device()->MicrophoneVolume(&micVol) != 0) {
     139           0 :       _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
     140           0 :                             "SetMicVolume() unable to get microphone volume");
     141           0 :       return -1;
     142             :     }
     143           0 :     if (micVol >= maxVol)
     144           0 :       return 0;
     145             :   }
     146             : 
     147             :   // Round the value and avoid floating point computation.
     148           0 :   micVol = (uint32_t)((volume * maxVol + (int)(kMaxVolumeLevel / 2)) /
     149             :                       (kMaxVolumeLevel));
     150             : 
     151             :   // set the actual volume using the audio mixer
     152           0 :   if (_shared->audio_device()->SetMicrophoneVolume(micVol) != 0) {
     153           0 :     _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
     154           0 :                           "SetMicVolume() failed to set mic volume");
     155           0 :     return -1;
     156             :   }
     157           0 :   return 0;
     158             : }
     159             : 
     160           0 : int VoEVolumeControlImpl::GetMicVolume(unsigned int& volume) {
     161           0 :   if (!_shared->statistics().Initialized()) {
     162           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     163           0 :     return -1;
     164             :   }
     165             : 
     166           0 :   uint32_t micVol(0);
     167           0 :   uint32_t maxVol(0);
     168             : 
     169           0 :   if (_shared->audio_device()->MicrophoneVolume(&micVol) != 0) {
     170           0 :     _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
     171           0 :                           "GetMicVolume() unable to get microphone volume");
     172           0 :     return -1;
     173             :   }
     174             : 
     175             :   // scale: [0, MaxMicrophoneVolume] -> [0, kMaxVolumeLevel]
     176           0 :   if (_shared->audio_device()->MaxMicrophoneVolume(&maxVol) != 0) {
     177           0 :     _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
     178           0 :                           "GetMicVolume() unable to get max microphone volume");
     179           0 :     return -1;
     180             :   }
     181           0 :   if (micVol < maxVol) {
     182             :     // Round the value and avoid floating point calculation.
     183           0 :     volume =
     184           0 :         (uint32_t)((micVol * kMaxVolumeLevel + (int)(maxVol / 2)) / (maxVol));
     185             :   } else {
     186             :     // Truncate the value to the kMaxVolumeLevel.
     187           0 :     volume = kMaxVolumeLevel;
     188             :   }
     189           0 :   return 0;
     190             : }
     191             : 
     192           0 : int VoEVolumeControlImpl::SetInputMute(int channel, bool enable) {
     193             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     194             :                "SetInputMute(channel=%d, enable=%d)", channel, enable);
     195             : 
     196           0 :   if (!_shared->statistics().Initialized()) {
     197           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     198           0 :     return -1;
     199             :   }
     200           0 :   if (channel == -1) {
     201             :     // Mute before demultiplexing <=> affects all channels
     202           0 :     return _shared->transmit_mixer()->SetMute(enable);
     203             :   }
     204             :   // Mute after demultiplexing <=> affects one channel only
     205           0 :   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
     206           0 :   voe::Channel* channelPtr = ch.channel();
     207           0 :   if (channelPtr == NULL) {
     208           0 :     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
     209           0 :                           "SetInputMute() failed to locate channel");
     210           0 :     return -1;
     211             :   }
     212           0 :   return channelPtr->SetInputMute(enable);
     213             : }
     214             : 
     215           0 : int VoEVolumeControlImpl::GetInputMute(int channel, bool& enabled) {
     216           0 :   if (!_shared->statistics().Initialized()) {
     217           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     218           0 :     return -1;
     219             :   }
     220           0 :   if (channel == -1) {
     221           0 :     enabled = _shared->transmit_mixer()->Mute();
     222             :   } else {
     223           0 :     voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
     224           0 :     voe::Channel* channelPtr = ch.channel();
     225           0 :     if (channelPtr == NULL) {
     226           0 :       _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
     227           0 :                             "SetInputMute() failed to locate channel");
     228           0 :       return -1;
     229             :     }
     230           0 :     enabled = channelPtr->InputMute();
     231             :   }
     232           0 :   return 0;
     233             : }
     234             : 
     235           0 : int VoEVolumeControlImpl::GetSpeechInputLevel(unsigned int& level) {
     236           0 :   if (!_shared->statistics().Initialized()) {
     237           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     238           0 :     return -1;
     239             :   }
     240           0 :   int8_t currentLevel = _shared->transmit_mixer()->AudioLevel();
     241           0 :   level = static_cast<unsigned int>(currentLevel);
     242           0 :   return 0;
     243             : }
     244             : 
     245           0 : int VoEVolumeControlImpl::GetSpeechOutputLevel(int channel,
     246             :                                                unsigned int& level) {
     247           0 :   if (!_shared->statistics().Initialized()) {
     248           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     249           0 :     return -1;
     250             :   }
     251           0 :   if (channel == -1) {
     252           0 :     return _shared->output_mixer()->GetSpeechOutputLevel((uint32_t&)level);
     253             :   } else {
     254           0 :     voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
     255           0 :     voe::Channel* channelPtr = ch.channel();
     256           0 :     if (channelPtr == NULL) {
     257           0 :       _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
     258           0 :                             "GetSpeechOutputLevel() failed to locate channel");
     259           0 :       return -1;
     260             :     }
     261           0 :     channelPtr->GetSpeechOutputLevel((uint32_t&)level);
     262             :   }
     263           0 :   return 0;
     264             : }
     265             : 
     266           0 : int VoEVolumeControlImpl::GetSpeechInputLevelFullRange(unsigned int& level) {
     267           0 :   if (!_shared->statistics().Initialized()) {
     268           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     269           0 :     return -1;
     270             :   }
     271           0 :   int16_t currentLevel = _shared->transmit_mixer()->AudioLevelFullRange();
     272           0 :   level = static_cast<unsigned int>(currentLevel);
     273           0 :   return 0;
     274             : }
     275             : 
     276           0 : int VoEVolumeControlImpl::GetSpeechOutputLevelFullRange(int channel,
     277             :                                                         unsigned int& level) {
     278           0 :   if (!_shared->statistics().Initialized()) {
     279           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     280           0 :     return -1;
     281             :   }
     282           0 :   if (channel == -1) {
     283           0 :     return _shared->output_mixer()->GetSpeechOutputLevelFullRange(
     284           0 :         (uint32_t&)level);
     285             :   } else {
     286           0 :     voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
     287           0 :     voe::Channel* channelPtr = ch.channel();
     288           0 :     if (channelPtr == NULL) {
     289           0 :       _shared->SetLastError(
     290             :           VE_CHANNEL_NOT_VALID, kTraceError,
     291           0 :           "GetSpeechOutputLevelFullRange() failed to locate channel");
     292           0 :       return -1;
     293             :     }
     294           0 :     channelPtr->GetSpeechOutputLevelFullRange((uint32_t&)level);
     295             :   }
     296           0 :   return 0;
     297             : }
     298             : 
     299           0 : int VoEVolumeControlImpl::SetChannelOutputVolumeScaling(int channel,
     300             :                                                         float scaling) {
     301             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     302             :                "SetChannelOutputVolumeScaling(channel=%d, scaling=%3.2f)",
     303             :                channel, scaling);
     304           0 :   if (!_shared->statistics().Initialized()) {
     305           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     306           0 :     return -1;
     307             :   }
     308           0 :   if (scaling < kMinOutputVolumeScaling || scaling > kMaxOutputVolumeScaling) {
     309           0 :     _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
     310           0 :                           "SetChannelOutputVolumeScaling() invalid parameter");
     311           0 :     return -1;
     312             :   }
     313           0 :   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
     314           0 :   voe::Channel* channelPtr = ch.channel();
     315           0 :   if (channelPtr == NULL) {
     316           0 :     _shared->SetLastError(
     317             :         VE_CHANNEL_NOT_VALID, kTraceError,
     318           0 :         "SetChannelOutputVolumeScaling() failed to locate channel");
     319           0 :     return -1;
     320             :   }
     321           0 :   return channelPtr->SetChannelOutputVolumeScaling(scaling);
     322             : }
     323             : 
     324           0 : int VoEVolumeControlImpl::GetChannelOutputVolumeScaling(int channel,
     325             :                                                         float& scaling) {
     326           0 :   if (!_shared->statistics().Initialized()) {
     327           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     328           0 :     return -1;
     329             :   }
     330           0 :   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
     331           0 :   voe::Channel* channelPtr = ch.channel();
     332           0 :   if (channelPtr == NULL) {
     333           0 :     _shared->SetLastError(
     334             :         VE_CHANNEL_NOT_VALID, kTraceError,
     335           0 :         "GetChannelOutputVolumeScaling() failed to locate channel");
     336           0 :     return -1;
     337             :   }
     338           0 :   return channelPtr->GetChannelOutputVolumeScaling(scaling);
     339             : }
     340             : 
     341           0 : int VoEVolumeControlImpl::SetOutputVolumePan(int channel,
     342             :                                              float left,
     343             :                                              float right) {
     344             :   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
     345             :                "SetOutputVolumePan(channel=%d, left=%2.1f, right=%2.1f)",
     346             :                channel, left, right);
     347             : 
     348           0 :   if (!_shared->statistics().Initialized()) {
     349           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     350           0 :     return -1;
     351             :   }
     352             : 
     353           0 :   bool available(false);
     354           0 :   _shared->audio_device()->StereoPlayoutIsAvailable(&available);
     355           0 :   if (!available) {
     356           0 :     _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
     357           0 :                           "SetOutputVolumePan() stereo playout not supported");
     358           0 :     return -1;
     359             :   }
     360           0 :   if ((left < kMinOutputVolumePanning) || (left > kMaxOutputVolumePanning) ||
     361           0 :       (right < kMinOutputVolumePanning) || (right > kMaxOutputVolumePanning)) {
     362           0 :     _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
     363           0 :                           "SetOutputVolumePan() invalid parameter");
     364           0 :     return -1;
     365             :   }
     366             : 
     367           0 :   if (channel == -1) {
     368             :     // Master balance (affectes the signal after output mixing)
     369           0 :     return _shared->output_mixer()->SetOutputVolumePan(left, right);
     370             :   }
     371             :   // Per-channel balance (affects the signal before output mixing)
     372           0 :   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
     373           0 :   voe::Channel* channelPtr = ch.channel();
     374           0 :   if (channelPtr == NULL) {
     375           0 :     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
     376           0 :                           "SetOutputVolumePan() failed to locate channel");
     377           0 :     return -1;
     378             :   }
     379           0 :   return channelPtr->SetOutputVolumePan(left, right);
     380             : }
     381             : 
     382           0 : int VoEVolumeControlImpl::GetOutputVolumePan(int channel,
     383             :                                              float& left,
     384             :                                              float& right) {
     385           0 :   if (!_shared->statistics().Initialized()) {
     386           0 :     _shared->SetLastError(VE_NOT_INITED, kTraceError);
     387           0 :     return -1;
     388             :   }
     389             : 
     390           0 :   bool available(false);
     391           0 :   _shared->audio_device()->StereoPlayoutIsAvailable(&available);
     392           0 :   if (!available) {
     393           0 :     _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
     394           0 :                           "GetOutputVolumePan() stereo playout not supported");
     395           0 :     return -1;
     396             :   }
     397             : 
     398           0 :   if (channel == -1) {
     399           0 :     return _shared->output_mixer()->GetOutputVolumePan(left, right);
     400             :   }
     401           0 :   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
     402           0 :   voe::Channel* channelPtr = ch.channel();
     403           0 :   if (channelPtr == NULL) {
     404           0 :     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
     405           0 :                           "GetOutputVolumePan() failed to locate channel");
     406           0 :     return -1;
     407             :   }
     408           0 :   return channelPtr->GetOutputVolumePan(left, right);
     409             : }
     410             : 
     411             : }  // namespace webrtc

Generated by: LCOV version 1.13