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/interface/module_common_types.h" 13 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 14 #include "webrtc/voice_engine/level_indicator.h" 15 16 namespace webrtc { 17 18 namespace 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 23 const 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 27 AudioLevel::AudioLevel() : 28 _critSect(*CriticalSectionWrapper::CreateCriticalSection()), 29 _absMax(0), 30 _count(0), 31 _currentLevel(0), 32 _currentLevelFullRange(0) { 33 } 34 35 AudioLevel::~AudioLevel() { 36 delete &_critSect; 37 } 38 39 void AudioLevel::Clear() 40 { 41 CriticalSectionScoped cs(&_critSect); 42 _absMax = 0; 43 _count = 0; 44 _currentLevel = 0; 45 _currentLevelFullRange = 0; 46 } 47 48 void 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 89 int8_t AudioLevel::Level() const 90 { 91 CriticalSectionScoped cs(&_critSect); 92 return _currentLevel; 93 } 94 95 int16_t AudioLevel::LevelFullRange() const 96 { 97 CriticalSectionScoped cs(&_critSect); 98 return _currentLevelFullRange; 99 } 100 101 } // namespace voe 102 103 } // namespace webrtc 104