blob: a32527c2d82310f7a270aae527fdc2ee889ef838 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
andrew@webrtc.org63a50982012-05-02 23:56:37 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000011#include "critical_section_wrapper.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012#include "level_indicator.h"
13#include "module_common_types.h"
14#include "signal_processing_library.h"
15
16namespace webrtc {
17
18namespace voe {
19
niklase@google.com470e71d2011-07-07 08:21:25 +000020// 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 WebRtc_Word8 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() :
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000028 _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
niklase@google.com470e71d2011-07-07 08:21:25 +000029 _absMax(0),
30 _count(0),
31 _currentLevel(0),
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000032 _currentLevelFullRange(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +000033}
34
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000035AudioLevel::~AudioLevel() {
niklase@google.com470e71d2011-07-07 08:21:25 +000036}
37
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000038void AudioLevel::Clear()
niklase@google.com470e71d2011-07-07 08:21:25 +000039{
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000040 CriticalSectionScoped cs(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +000041 _absMax = 0;
42 _count = 0;
43 _currentLevel = 0;
44 _currentLevelFullRange = 0;
45}
46
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000047void AudioLevel::ComputeLevel(const AudioFrame& audioFrame)
niklase@google.com470e71d2011-07-07 08:21:25 +000048{
49 WebRtc_Word16 absValue(0);
50
51 // Check speech level (works for 2 channels as well)
52 absValue = WebRtcSpl_MaxAbsValueW16(
andrew@webrtc.org63a50982012-05-02 23:56:37 +000053 audioFrame.data_,
54 audioFrame.samples_per_channel_*audioFrame.num_channels_);
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000055
56 // Protect member access using a lock since this method is called on a
57 // dedicated audio thread in the RecordedDataIsAvailable() callback.
58 CriticalSectionScoped cs(&_critSect);
59
niklase@google.com470e71d2011-07-07 08:21:25 +000060 if (absValue > _absMax)
61 _absMax = absValue;
62
63 // Update level approximately 10 times per second
64 if (_count++ == kUpdateFrequency)
65 {
66 _currentLevelFullRange = _absMax;
67
68 _count = 0;
69
70 // Highest value for a WebRtc_Word16 is 0x7fff = 32767
71 // Divide with 1000 to get in the range of 0-32 which is the range of
72 // the permutation vector
73 WebRtc_Word32 position = _absMax/1000;
74
75 // Make it less likely that the bar stays at position 0. I.e. only if
76 // its in the range 0-250 (instead of 0-1000)
77 if ((position == 0) && (_absMax > 250))
78 {
79 position = 1;
80 }
81 _currentLevel = permutation[position];
82
83 // Decay the absolute maximum (divide by 4)
84 _absMax >>= 2;
85 }
86}
87
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000088WebRtc_Word8 AudioLevel::Level() const
niklase@google.com470e71d2011-07-07 08:21:25 +000089{
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000090 CriticalSectionScoped cs(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +000091 return _currentLevel;
92}
93
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000094WebRtc_Word16 AudioLevel::LevelFullRange() const
niklase@google.com470e71d2011-07-07 08:21:25 +000095{
henrika@webrtc.orgd108a462013-04-03 11:25:31 +000096 CriticalSectionScoped cs(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +000097 return _currentLevelFullRange;
98}
99
100} // namespace voe
101
102} // namespace webrtc