blob: 61dfbcda87ade8e660a811acbad3883562ce6ccb [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +00001/*
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
pbos@webrtc.org471ae722013-05-21 13:52:32 +000011#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"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000015
16namespace webrtc {
17
18namespace voe {
19
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +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
pbos@webrtc.org54f03bc2013-04-09 10:09:10 +000023const int8_t permutation[33] =
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000024 {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.orgc4efe712013-04-03 11:25:31 +000028 _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000029 _absMax(0),
30 _count(0),
31 _currentLevel(0),
henrika@webrtc.orgc4efe712013-04-03 11:25:31 +000032 _currentLevelFullRange(0) {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000033}
34
henrika@webrtc.orgc4efe712013-04-03 11:25:31 +000035AudioLevel::~AudioLevel() {
henrika@webrtc.org9e8a4012013-04-03 11:58:12 +000036 delete &_critSect;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000037}
38
henrika@webrtc.orgc4efe712013-04-03 11:25:31 +000039void AudioLevel::Clear()
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000040{
henrika@webrtc.orgc4efe712013-04-03 11:25:31 +000041 CriticalSectionScoped cs(&_critSect);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000042 _absMax = 0;
43 _count = 0;
44 _currentLevel = 0;
45 _currentLevelFullRange = 0;
46}
47
henrika@webrtc.orgc4efe712013-04-03 11:25:31 +000048void AudioLevel::ComputeLevel(const AudioFrame& audioFrame)
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000049{
pbos@webrtc.org54f03bc2013-04-09 10:09:10 +000050 int16_t absValue(0);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000051
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_);
henrika@webrtc.orgc4efe712013-04-03 11:25:31 +000056
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
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000061 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
pbos@webrtc.org54f03bc2013-04-09 10:09:10 +000071 // Highest value for a int16_t is 0x7fff = 32767
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000072 // Divide with 1000 to get in the range of 0-32 which is the range of
73 // the permutation vector
pbos@webrtc.org54f03bc2013-04-09 10:09:10 +000074 int32_t position = _absMax/1000;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000075
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
pbos@webrtc.org54f03bc2013-04-09 10:09:10 +000089int8_t AudioLevel::Level() const
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000090{
henrika@webrtc.orgc4efe712013-04-03 11:25:31 +000091 CriticalSectionScoped cs(&_critSect);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000092 return _currentLevel;
93}
94
pbos@webrtc.org54f03bc2013-04-09 10:09:10 +000095int16_t AudioLevel::LevelFullRange() const
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000096{
henrika@webrtc.orgc4efe712013-04-03 11:25:31 +000097 CriticalSectionScoped cs(&_critSect);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000098 return _currentLevelFullRange;
99}
100
101} // namespace voe
102
pbos@webrtc.org3b89e102013-07-03 15:12:26 +0000103} // namespace webrtc