andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 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 | |
pbos@webrtc.org | 471ae72 | 2013-05-21 13:52:32 +0000 | [diff] [blame] | 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" |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 15 | |
| 16 | namespace webrtc { |
| 17 | |
| 18 | namespace voe { |
| 19 | |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 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 |
pbos@webrtc.org | 54f03bc | 2013-04-09 10:09:10 +0000 | [diff] [blame] | 23 | const int8_t permutation[33] = |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 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() : |
henrika@webrtc.org | c4efe71 | 2013-04-03 11:25:31 +0000 | [diff] [blame] | 28 | _critSect(*CriticalSectionWrapper::CreateCriticalSection()), |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 29 | _absMax(0), |
| 30 | _count(0), |
| 31 | _currentLevel(0), |
henrika@webrtc.org | c4efe71 | 2013-04-03 11:25:31 +0000 | [diff] [blame] | 32 | _currentLevelFullRange(0) { |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 33 | } |
| 34 | |
henrika@webrtc.org | c4efe71 | 2013-04-03 11:25:31 +0000 | [diff] [blame] | 35 | AudioLevel::~AudioLevel() { |
henrika@webrtc.org | 9e8a401 | 2013-04-03 11:58:12 +0000 | [diff] [blame] | 36 | delete &_critSect; |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 37 | } |
| 38 | |
henrika@webrtc.org | c4efe71 | 2013-04-03 11:25:31 +0000 | [diff] [blame] | 39 | void AudioLevel::Clear() |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 40 | { |
henrika@webrtc.org | c4efe71 | 2013-04-03 11:25:31 +0000 | [diff] [blame] | 41 | CriticalSectionScoped cs(&_critSect); |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 42 | _absMax = 0; |
| 43 | _count = 0; |
| 44 | _currentLevel = 0; |
| 45 | _currentLevelFullRange = 0; |
| 46 | } |
| 47 | |
henrika@webrtc.org | c4efe71 | 2013-04-03 11:25:31 +0000 | [diff] [blame] | 48 | void AudioLevel::ComputeLevel(const AudioFrame& audioFrame) |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 49 | { |
pbos@webrtc.org | 54f03bc | 2013-04-09 10:09:10 +0000 | [diff] [blame] | 50 | int16_t absValue(0); |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 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_); |
henrika@webrtc.org | c4efe71 | 2013-04-03 11:25:31 +0000 | [diff] [blame] | 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 | |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 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 | |
pbos@webrtc.org | 54f03bc | 2013-04-09 10:09:10 +0000 | [diff] [blame] | 71 | // Highest value for a int16_t is 0x7fff = 32767 |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 72 | // Divide with 1000 to get in the range of 0-32 which is the range of |
| 73 | // the permutation vector |
pbos@webrtc.org | 54f03bc | 2013-04-09 10:09:10 +0000 | [diff] [blame] | 74 | int32_t position = _absMax/1000; |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 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 | |
pbos@webrtc.org | 54f03bc | 2013-04-09 10:09:10 +0000 | [diff] [blame] | 89 | int8_t AudioLevel::Level() const |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 90 | { |
henrika@webrtc.org | c4efe71 | 2013-04-03 11:25:31 +0000 | [diff] [blame] | 91 | CriticalSectionScoped cs(&_critSect); |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 92 | return _currentLevel; |
| 93 | } |
| 94 | |
pbos@webrtc.org | 54f03bc | 2013-04-09 10:09:10 +0000 | [diff] [blame] | 95 | int16_t AudioLevel::LevelFullRange() const |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 96 | { |
henrika@webrtc.org | c4efe71 | 2013-04-03 11:25:31 +0000 | [diff] [blame] | 97 | CriticalSectionScoped cs(&_critSect); |
andrew@webrtc.org | b015cbe | 2012-10-22 18:19:23 +0000 | [diff] [blame] | 98 | return _currentLevelFullRange; |
| 99 | } |
| 100 | |
| 101 | } // namespace voe |
| 102 | |
pbos@webrtc.org | 3b89e10 | 2013-07-03 15:12:26 +0000 | [diff] [blame] | 103 | } // namespace webrtc |