Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(709)

Side by Side Diff: webrtc/modules/audio_processing/rms_level.cc

Issue 2535523002: Refactor RMSLevel and give it new functionality (Closed)
Patch Set: Fixing win64 compile Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/audio_processing/rms_level.h" 11 #include "webrtc/modules/audio_processing/rms_level.h"
12 12
13 #include <math.h> 13 #include <math.h>
14 #include <algorithm>
15 #include <numeric>
14 16
15 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
16 18
17 namespace webrtc { 19 namespace webrtc {
18 20 namespace {
19 static const float kMaxSquaredLevel = 32768 * 32768; 21 static constexpr float kMaxSquaredLevel = 32768 * 32768;
22 static constexpr int kMinLevelDb = 127;
23 // kMinLevel is the level corresponding to kMinLevelDb, that is 10^(-127/10).
24 static constexpr float kMinLevel = 1.995262314968883e-13f;
peah-webrtc 2016/11/29 08:57:13 Can this be computed from kMinLevelDb using a cons
hlundin-webrtc 2016/11/29 10:24:54 Already tried, but failed. Cannot use static_asser
25 } // namespace
20 26
21 RMSLevel::RMSLevel() 27 RMSLevel::RMSLevel()
22 : sum_square_(0), 28 : sum_square_(0),
peah-webrtc 2016/11/29 08:57:12 0.f
23 sample_count_(0) {} 29 sample_count_(0),
30 max_mean_square_(0) {}
peah-webrtc 2016/11/29 08:57:13 0.f
peah-webrtc 2016/11/29 08:57:13 Would it make sense to do a call to Reset() inside
hlundin-webrtc 2016/11/29 10:24:54 Done.
24 31
25 RMSLevel::~RMSLevel() {} 32 RMSLevel::~RMSLevel() = default;
26 33
27 void RMSLevel::Reset() { 34 void RMSLevel::Reset() {
28 sum_square_ = 0; 35 sum_square_ = 0;
peah-webrtc 2016/11/29 08:57:13 0.f;
hlundin-webrtc 2016/11/29 10:24:54 Done.
29 sample_count_ = 0; 36 sample_count_ = 0;
37 max_mean_square_ = 0;
peah-webrtc 2016/11/29 08:57:13 0.f;
hlundin-webrtc 2016/11/29 10:24:54 Done.
30 } 38 }
31 39
32 void RMSLevel::Process(const int16_t* data, size_t length) { 40 void RMSLevel::Process(rtc::ArrayView<const int16_t> data) {
33 for (size_t i = 0; i < length; ++i) { 41 if (data.empty()) {
34 sum_square_ += data[i] * data[i]; 42 return;
35 } 43 }
36 sample_count_ += length; 44
45 const float sum_square =
46 std::accumulate(data.begin(), data.end(), 0.f,
47 [](float a, int16_t b) { return a + b * b; });
48 RTC_DCHECK_GE(sum_square, 0.f);
49 sum_square_ += sum_square;
50 sample_count_ += data.size();
51
52 max_mean_square_ = std::max(max_mean_square_, sum_square / data.size());
peah-webrtc 2016/11/29 08:57:13 Why not do the division only at the call of Averag
hlundin-webrtc 2016/11/29 10:24:54 Changed the implementation to cope with variable b
37 } 53 }
38 54
39 void RMSLevel::ProcessMuted(size_t length) { 55 void RMSLevel::ProcessMuted(size_t length) {
40 sample_count_ += length; 56 sample_count_ += length;
41 } 57 }
42 58
59 namespace {
peah-webrtc 2016/11/29 08:57:13 Is there a special reason for having two anonymous
hlundin-webrtc 2016/11/29 10:24:54 I thought it made sense to have the code close to
60 // Calculates the normalized RMS value from a mean square value. The input
61 // should be the sum of squared samples divided by the number of samples. The
62 // value will be normalized to full range before computing the RMS, wich is
63 // returned as a negated dBfs. That is, 0 is full amplitude while 127 is very
64 // faint.
65 int CalcRms(float mean_square) {
peah-webrtc 2016/11/29 08:57:12 I would suggest avoiding the abbreviation Calc sin
hlundin-webrtc 2016/11/29 10:24:54 Done.
66 if (mean_square <= kMinLevel * kMaxSquaredLevel) {
67 // Very faint; simply return the minimum value.
68 return kMinLevelDb;
69 }
70 // Normalize by the max level.
71 const float mean_square_norm = mean_square / kMaxSquaredLevel;
72 RTC_DCHECK_GT(mean_square_norm, kMinLevel);
73 // 20log_10(x^0.5) = 10log_10(x)
74 const float rms = 10 * log10(mean_square_norm);
peah-webrtc 2016/11/29 08:57:12 10.f
hlundin-webrtc 2016/11/29 10:24:55 Done.
75 RTC_DCHECK_LE(rms, 0);
peah-webrtc 2016/11/29 08:57:12 0.f
hlundin-webrtc 2016/11/29 10:24:54 Done.
76 RTC_DCHECK_GT(rms, -kMinLevelDb);
77 // Return the negated value.
78 return static_cast<int>(-rms + 0.5);
peah-webrtc 2016/11/29 08:57:13 0.5f
hlundin-webrtc 2016/11/29 10:24:54 Done.
79 }
80 } // namespace
81
43 int RMSLevel::RMS() { 82 int RMSLevel::RMS() {
44 if (sample_count_ == 0 || sum_square_ == 0) { 83 int rms =
45 Reset(); 84 (sample_count_ == 0) ? kMinLevelDb : CalcRms(sum_square_ / sample_count_);
46 return kMinLevel; 85 Reset();
47 } 86 return rms;
87 }
48 88
49 // Normalize by the max level. 89 RMSLevel::Levels RMSLevel::AverageAndPeak() {
50 float rms = sum_square_ / (sample_count_ * kMaxSquaredLevel); 90 // Note that max_mean_square_ is already divided by the number of samples.
51 // 20log_10(x^0.5) = 10log_10(x) 91 Levels levels = (sample_count_ == 0)
52 rms = 10 * log10(rms); 92 ? Levels{kMinLevelDb, kMinLevelDb}
53 RTC_DCHECK_LE(rms, 0); 93 : Levels{CalcRms(sum_square_ / sample_count_),
54 if (rms < -kMinLevel) 94 CalcRms(max_mean_square_)};
55 rms = -kMinLevel;
56
57 rms = -rms;
58 Reset(); 95 Reset();
59 return static_cast<int>(rms + 0.5); 96 return levels;
60 } 97 }
61 98
62 } // namespace webrtc 99 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698