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 
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 
AudioLevel()27 AudioLevel::AudioLevel() :
28     _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
29     _absMax(0),
30     _count(0),
31     _currentLevel(0),
32     _currentLevelFullRange(0) {
33 }
34 
~AudioLevel()35 AudioLevel::~AudioLevel() {
36     delete &_critSect;
37 }
38 
Clear()39 void AudioLevel::Clear()
40 {
41     CriticalSectionScoped cs(&_critSect);
42     _absMax = 0;
43     _count = 0;
44     _currentLevel = 0;
45     _currentLevelFullRange = 0;
46 }
47 
ComputeLevel(const AudioFrame & audioFrame)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 
Level() const89 int8_t AudioLevel::Level() const
90 {
91     CriticalSectionScoped cs(&_critSect);
92     return _currentLevel;
93 }
94 
LevelFullRange() const95 int16_t AudioLevel::LevelFullRange() const
96 {
97     CriticalSectionScoped cs(&_critSect);
98     return _currentLevelFullRange;
99 }
100 
101 }  // namespace voe
102 
103 }  // namespace webrtc
104