Home | History | Annotate | Download | only in voice_engine
      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