| /* | 
 |  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 
 |  * | 
 |  *  Use of this source code is governed by a BSD-style license | 
 |  *  that can be found in the LICENSE file in the root of the source | 
 |  *  tree. An additional intellectual property rights grant can be found | 
 |  *  in the file PATENTS.  All contributing project authors may | 
 |  *  be found in the AUTHORS file in the root of the source tree. | 
 |  */ | 
 |  | 
 | #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" | 
 | #include "webrtc/modules/interface/module_common_types.h" | 
 | #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" | 
 | #include "webrtc/voice_engine/level_indicator.h" | 
 |  | 
 | namespace webrtc { | 
 |  | 
 | namespace voe { | 
 |  | 
 | // Number of bars on the indicator. | 
 | // Note that the number of elements is specified because we are indexing it | 
 | // in the range of 0-32 | 
 | const int8_t permutation[33] = | 
 |     {0,1,2,3,4,4,5,5,5,5,6,6,6,6,6,7,7,7,7,8,8,8,9,9,9,9,9,9,9,9,9,9,9}; | 
 |  | 
 |  | 
 | AudioLevel::AudioLevel() : | 
 |     _critSect(*CriticalSectionWrapper::CreateCriticalSection()), | 
 |     _absMax(0), | 
 |     _count(0), | 
 |     _currentLevel(0), | 
 |     _currentLevelFullRange(0) { | 
 | } | 
 |  | 
 | AudioLevel::~AudioLevel() { | 
 |     delete &_critSect; | 
 | } | 
 |  | 
 | void AudioLevel::Clear() | 
 | { | 
 |     CriticalSectionScoped cs(&_critSect); | 
 |     _absMax = 0; | 
 |     _count = 0; | 
 |     _currentLevel = 0; | 
 |     _currentLevelFullRange = 0; | 
 | } | 
 |  | 
 | void AudioLevel::ComputeLevel(const AudioFrame& audioFrame) | 
 | { | 
 |     int16_t absValue(0); | 
 |  | 
 |     // Check speech level (works for 2 channels as well) | 
 |     absValue = WebRtcSpl_MaxAbsValueW16( | 
 |         audioFrame.data_, | 
 |         audioFrame.samples_per_channel_*audioFrame.num_channels_); | 
 |  | 
 |     // Protect member access using a lock since this method is called on a | 
 |     // dedicated audio thread in the RecordedDataIsAvailable() callback. | 
 |     CriticalSectionScoped cs(&_critSect); | 
 |  | 
 |     if (absValue > _absMax) | 
 |     _absMax = absValue; | 
 |  | 
 |     // Update level approximately 10 times per second | 
 |     if (_count++ == kUpdateFrequency) | 
 |     { | 
 |         _currentLevelFullRange = _absMax; | 
 |  | 
 |         _count = 0; | 
 |  | 
 |         // Highest value for a int16_t is 0x7fff = 32767 | 
 |         // Divide with 1000 to get in the range of 0-32 which is the range of | 
 |         // the permutation vector | 
 |         int32_t position = _absMax/1000; | 
 |  | 
 |         // Make it less likely that the bar stays at position 0. I.e. only if | 
 |         // its in the range 0-250 (instead of 0-1000) | 
 |         if ((position == 0) && (_absMax > 250)) | 
 |         { | 
 |             position = 1; | 
 |         } | 
 |         _currentLevel = permutation[position]; | 
 |  | 
 |         // Decay the absolute maximum (divide by 4) | 
 |         _absMax >>= 2; | 
 |     } | 
 | } | 
 |  | 
 | int8_t AudioLevel::Level() const | 
 | { | 
 |     CriticalSectionScoped cs(&_critSect); | 
 |     return _currentLevel; | 
 | } | 
 |  | 
 | int16_t AudioLevel::LevelFullRange() const | 
 | { | 
 |     CriticalSectionScoped cs(&_critSect); | 
 |     return _currentLevelFullRange; | 
 | } | 
 |  | 
 | }  // namespace voe | 
 |  | 
 | }  // namespace webrtc |