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 <assert.h>
14 #include <math.h>
15 
16 namespace webrtc {
17 
18 static const float kMaxSquaredLevel = 32768 * 32768;
19 
RMSLevel()20 RMSLevel::RMSLevel()
21     : sum_square_(0),
22       sample_count_(0) {}
23 
~RMSLevel()24 RMSLevel::~RMSLevel() {}
25 
Reset()26 void RMSLevel::Reset() {
27   sum_square_ = 0;
28   sample_count_ = 0;
29 }
30 
Process(const int16_t * data,size_t length)31 void RMSLevel::Process(const int16_t* data, size_t length) {
32   for (size_t i = 0; i < length; ++i) {
33     sum_square_ += data[i] * data[i];
34   }
35   sample_count_ += length;
36 }
37 
ProcessMuted(size_t length)38 void RMSLevel::ProcessMuted(size_t length) {
39   sample_count_ += length;
40 }
41 
RMS()42 int RMSLevel::RMS() {
43   if (sample_count_ == 0 || sum_square_ == 0) {
44     Reset();
45     return kMinLevel;
46   }
47 
48   // Normalize by the max level.
49   float rms = sum_square_ / (sample_count_ * kMaxSquaredLevel);
50   // 20log_10(x^0.5) = 10log_10(x)
51   rms = 10 * log10(rms);
52   assert(rms <= 0);
53   if (rms < -kMinLevel)
54     rms = -kMinLevel;
55 
56   rms = -rms;
57   Reset();
58   return static_cast<int>(rms + 0.5);
59 }
60 
61 }  // namespace webrtc
62