13cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org/*
23cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
33cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org *
43cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
53cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
63cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
73cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
83cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
93cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org */
103cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
113cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org#include "webrtc/modules/audio_processing/rms_level.h"
123cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
133cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org#include <assert.h>
143cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org#include <math.h>
153cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
163cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.orgnamespace webrtc {
173cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
187d20ddad4b04bd9811abc12a91a7061cbdef2b29andrew@webrtc.orgstatic const float kMaxSquaredLevel = 32768 * 32768;
193cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
203cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.orgRMSLevel::RMSLevel()
217d20ddad4b04bd9811abc12a91a7061cbdef2b29andrew@webrtc.org    : sum_square_(0),
223cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org      sample_count_(0) {}
233cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
243cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.orgRMSLevel::~RMSLevel() {}
253cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
263cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.orgvoid RMSLevel::Reset() {
277d20ddad4b04bd9811abc12a91a7061cbdef2b29andrew@webrtc.org  sum_square_ = 0;
283cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  sample_count_ = 0;
293cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org}
303cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
313cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.orgvoid RMSLevel::Process(const int16_t* data, int length) {
323cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  for (int i = 0; i < length; ++i) {
333cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org    sum_square_ += data[i] * data[i];
343cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  }
353cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  sample_count_ += length;
363cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org}
373cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
383cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.orgvoid RMSLevel::ProcessMuted(int length) {
393cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  sample_count_ += length;
403cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org}
413cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
423cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.orgint RMSLevel::RMS() {
437d20ddad4b04bd9811abc12a91a7061cbdef2b29andrew@webrtc.org  if (sample_count_ == 0 || sum_square_ == 0) {
443cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org    Reset();
453cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org    return kMinLevel;
463cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  }
473cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
483cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  // Normalize by the max level.
493cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  float rms = sum_square_ / (sample_count_ * kMaxSquaredLevel);
503cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  // 20log_10(x^0.5) = 10log_10(x)
513cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  rms = 10 * log10(rms);
523cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  assert(rms <= 0);
533cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  if (rms < -kMinLevel)
543cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org    rms = -kMinLevel;
553cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
563cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  rms = -rms;
573cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  Reset();
583cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org  return static_cast<int>(rms + 0.5);
593cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org}
603cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org
613cd0f7c23453b72575e9c92bb7144fa3525abb10andrew@webrtc.org}  // namespace webrtc
62