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/common_audio/signal_processing/include/signal_processing_library.h" 12#include "webrtc/modules/include/module_common_types.h" 13#include "webrtc/system_wrappers/include/critical_section_wrapper.h" 14#include "webrtc/voice_engine/level_indicator.h" 15 16namespace webrtc { 17 18namespace voe { 19 20// Number of bars on the indicator. 21// Note that the number of elements is specified because we are indexing it 22// in the range of 0-32 23const int8_t permutation[33] = 24 {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}; 25 26 27AudioLevel::AudioLevel() : 28 _critSect(*CriticalSectionWrapper::CreateCriticalSection()), 29 _absMax(0), 30 _count(0), 31 _currentLevel(0), 32 _currentLevelFullRange(0) { 33} 34 35AudioLevel::~AudioLevel() { 36 delete &_critSect; 37} 38 39void AudioLevel::Clear() 40{ 41 CriticalSectionScoped cs(&_critSect); 42 _absMax = 0; 43 _count = 0; 44 _currentLevel = 0; 45 _currentLevelFullRange = 0; 46} 47 48void AudioLevel::ComputeLevel(const AudioFrame& audioFrame) 49{ 50 int16_t absValue(0); 51 52 // Check speech level (works for 2 channels as well) 53 absValue = WebRtcSpl_MaxAbsValueW16( 54 audioFrame.data_, 55 audioFrame.samples_per_channel_*audioFrame.num_channels_); 56 57 // Protect member access using a lock since this method is called on a 58 // dedicated audio thread in the RecordedDataIsAvailable() callback. 59 CriticalSectionScoped cs(&_critSect); 60 61 if (absValue > _absMax) 62 _absMax = absValue; 63 64 // Update level approximately 10 times per second 65 if (_count++ == kUpdateFrequency) 66 { 67 _currentLevelFullRange = _absMax; 68 69 _count = 0; 70 71 // Highest value for a int16_t is 0x7fff = 32767 72 // Divide with 1000 to get in the range of 0-32 which is the range of 73 // the permutation vector 74 int32_t position = _absMax/1000; 75 76 // Make it less likely that the bar stays at position 0. I.e. only if 77 // its in the range 0-250 (instead of 0-1000) 78 if ((position == 0) && (_absMax > 250)) 79 { 80 position = 1; 81 } 82 _currentLevel = permutation[position]; 83 84 // Decay the absolute maximum (divide by 4) 85 _absMax >>= 2; 86 } 87} 88 89int8_t AudioLevel::Level() const 90{ 91 CriticalSectionScoped cs(&_critSect); 92 return _currentLevel; 93} 94 95int16_t AudioLevel::LevelFullRange() const 96{ 97 CriticalSectionScoped cs(&_critSect); 98 return _currentLevelFullRange; 99} 100 101} // namespace voe 102 103} // namespace webrtc 104