LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_processing - rms_level.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 48 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2014 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/modules/audio_processing/rms_level.h"
      12             : 
      13             : #include <math.h>
      14             : #include <algorithm>
      15             : #include <numeric>
      16             : 
      17             : #include "webrtc/base/checks.h"
      18             : 
      19             : namespace webrtc {
      20             : namespace {
      21             : static constexpr float kMaxSquaredLevel = 32768 * 32768;
      22             : // kMinLevel is the level corresponding to kMinLevelDb, that is 10^(-127/10).
      23             : static constexpr float kMinLevel = 1.995262314968883e-13f;
      24             : 
      25             : // Calculates the normalized RMS value from a mean square value. The input
      26             : // should be the sum of squared samples divided by the number of samples. The
      27             : // value will be normalized to full range before computing the RMS, wich is
      28             : // returned as a negated dBfs. That is, 0 is full amplitude while 127 is very
      29             : // faint.
      30           0 : int ComputeRms(float mean_square) {
      31           0 :   if (mean_square <= kMinLevel * kMaxSquaredLevel) {
      32             :     // Very faint; simply return the minimum value.
      33           0 :     return RmsLevel::kMinLevelDb;
      34             :   }
      35             :   // Normalize by the max level.
      36           0 :   const float mean_square_norm = mean_square / kMaxSquaredLevel;
      37           0 :   RTC_DCHECK_GT(mean_square_norm, kMinLevel);
      38             :   // 20log_10(x^0.5) = 10log_10(x)
      39           0 :   const float rms = 10.f * log10(mean_square_norm);
      40           0 :   RTC_DCHECK_LE(rms, 0.f);
      41           0 :   RTC_DCHECK_GT(rms, -RmsLevel::kMinLevelDb);
      42             :   // Return the negated value.
      43           0 :   return static_cast<int>(-rms + 0.5f);
      44             : }
      45             : }  // namespace
      46             : 
      47           0 : RmsLevel::RmsLevel() {
      48           0 :   Reset();
      49           0 : }
      50             : 
      51             : RmsLevel::~RmsLevel() = default;
      52             : 
      53           0 : void RmsLevel::Reset() {
      54           0 :   sum_square_ = 0.f;
      55           0 :   sample_count_ = 0;
      56           0 :   max_sum_square_ = 0.f;
      57           0 :   block_size_ = rtc::Optional<size_t>();
      58           0 : }
      59             : 
      60           0 : void RmsLevel::Analyze(rtc::ArrayView<const int16_t> data) {
      61           0 :   if (data.empty()) {
      62           0 :     return;
      63             :   }
      64             : 
      65           0 :   CheckBlockSize(data.size());
      66             : 
      67             :   const float sum_square =
      68           0 :       std::accumulate(data.begin(), data.end(), 0.f,
      69           0 :                       [](float a, int16_t b) { return a + b * b; });
      70           0 :   RTC_DCHECK_GE(sum_square, 0.f);
      71           0 :   sum_square_ += sum_square;
      72           0 :   sample_count_ += data.size();
      73             : 
      74           0 :   max_sum_square_ = std::max(max_sum_square_, sum_square);
      75             : }
      76             : 
      77           0 : void RmsLevel::AnalyzeMuted(size_t length) {
      78           0 :   CheckBlockSize(length);
      79           0 :   sample_count_ += length;
      80           0 : }
      81             : 
      82           0 : int RmsLevel::Average() {
      83           0 :   int rms = (sample_count_ == 0) ? RmsLevel::kMinLevelDb
      84           0 :                                  : ComputeRms(sum_square_ / sample_count_);
      85           0 :   Reset();
      86           0 :   return rms;
      87             : }
      88             : 
      89           0 : RmsLevel::Levels RmsLevel::AverageAndPeak() {
      90             :   // Note that block_size_ should by design always be non-empty when
      91             :   // sample_count_ != 0. Also, the * operator of rtc::Optional enforces this
      92             :   // with a DCHECK.
      93           0 :   Levels levels = (sample_count_ == 0)
      94             :                       ? Levels{RmsLevel::kMinLevelDb, RmsLevel::kMinLevelDb}
      95           0 :                       : Levels{ComputeRms(sum_square_ / sample_count_),
      96           0 :                                ComputeRms(max_sum_square_ / *block_size_)};
      97           0 :   Reset();
      98           0 :   return levels;
      99             : }
     100             : 
     101           0 : void RmsLevel::CheckBlockSize(size_t block_size) {
     102           0 :   if (block_size_ != rtc::Optional<size_t>(block_size)) {
     103           0 :     Reset();
     104           0 :     block_size_ = rtc::Optional<size_t>(block_size);
     105             :   }
     106           0 : }
     107             : }  // namespace webrtc

Generated by: LCOV version 1.13