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

Side by Side Diff: webrtc/modules/audio_processing/level_controller/gain_applier.cc

Issue 2090583002: New module for the adaptive level controlling functionality in the audio processing module (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Corrected the initial behavior for the peak level estimate, and ensured a nonzero minimum peak leveā€¦ Created 4 years, 6 months 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
(Empty)
1 /*
2 * Copyright (c) 2016 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/level_controller/gain_applier.h"
12
13 #include <algorithm>
14
15 #include "webrtc/base/array_view.h"
16 #include "webrtc/base/checks.h"
17
18 #include "webrtc/modules/audio_processing/audio_buffer.h"
19 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h"
20
21 namespace webrtc {
22 namespace {
23
24 const float kMaxSampleValue = 32767.f;
25 const float kMinSampleValue = -32767.f;
26
27 int CountSaturations(rtc::ArrayView<const float> in) {
hlundin-webrtc 2016/06/27 11:21:14 You can implement this as a one-liner: return std
peah-webrtc 2016/06/27 22:51:47 Wow! Impressive! Thanks!!! Done.
28 int num_saturations = 0;
29 for (auto v : in) {
30 if (v >= kMaxSampleValue || v <= kMinSampleValue) {
31 ++num_saturations;
32 }
33 }
34 return num_saturations;
35 }
36
37 int CountSaturations(const AudioBuffer& audio) {
38 int num_saturations = 0;
39 for (size_t k = 0; k < audio.num_channels(); ++k) {
40 num_saturations += CountSaturations(rtc::ArrayView<const float>(
41 audio.channels_const_f()[k], audio.num_frames()));
42 }
43 return num_saturations;
44 }
45
46 void LimitToAllowedRange(rtc::ArrayView<float> x) {
47 for (auto& v : x) {
48 v = std::max(kMinSampleValue, v);
49 v = std::min(kMaxSampleValue, v);
50 }
51 }
52
53 void LimitToAllowedRange(AudioBuffer* audio) {
54 for (size_t k = 0; k < audio->num_channels(); ++k) {
55 LimitToAllowedRange(
56 rtc::ArrayView<float>(audio->channels_f()[k], audio->num_frames()));
57 }
58 }
59
60 float ApplyIncreasingGain(float new_gain,
61 float old_gain,
62 float step_size,
63 rtc::ArrayView<float> x) {
64 RTC_DCHECK_LT(0.f, step_size);
65 float gain = old_gain;
66 for (auto& x_v : x) {
hlundin-webrtc 2016/06/27 11:21:14 Stick to the same definition as above, and use v i
peah-webrtc 2016/06/27 22:51:47 Done.
67 gain = std::min(new_gain, gain + step_size);
68 x_v *= gain;
69 }
70 return gain;
71 }
72
73 float ApplyDecreasingGain(float new_gain,
74 float old_gain,
75 float step_size,
76 rtc::ArrayView<float> x) {
77 RTC_DCHECK_LT(0.f, step_size);
78 float gain = old_gain;
79 for (auto& x_v : x) {
80 gain = std::max(new_gain, gain - step_size);
81 x_v *= gain;
82 }
83 return gain;
84 }
85
86 void ApplyConstantGain(float gain, rtc::ArrayView<float> x) {
87 for (auto& x_v : x) {
88 x_v *= gain;
89 }
90 }
91
92 float ApplyGain(float new_gain,
93 float old_gain,
94 float step_size,
95 rtc::ArrayView<float> x) {
96 float last_applied_gain = new_gain;
hlundin-webrtc 2016/06/27 11:21:14 Not needed, with my suggestions below.
peah-webrtc 2016/06/27 22:51:47 Done.
97 if (new_gain == old_gain) {
98 ApplyConstantGain(new_gain, x);
hlundin-webrtc 2016/06/27 11:21:14 ApplyConstantGain(new_gain, x); return new_gain;
peah-webrtc 2016/06/27 22:51:47 Nice!!! Done.
99 } else if (new_gain > old_gain) {
100 last_applied_gain = ApplyIncreasingGain(new_gain, old_gain, step_size, x);
hlundin-webrtc 2016/06/27 11:21:14 return ApplyIncreasingGain(...
peah-webrtc 2016/06/27 22:51:47 Done.
101 } else {
102 last_applied_gain = ApplyDecreasingGain(new_gain, old_gain, step_size, x);
hlundin-webrtc 2016/06/27 11:21:14 return ApplyDecreasingGain(...
peah-webrtc 2016/06/27 22:51:47 Done.
103 }
104 return last_applied_gain;
105 }
106
107 } // namespace
108
109 GainApplier::GainApplier(ApmDataDumper* data_dumper)
110 : data_dumper_(data_dumper) {}
111
112 void GainApplier::Initialize(int sample_rate_hz) {
113 RTC_DCHECK_LE(0.f, sample_rate_hz);
hlundin-webrtc 2016/06/27 11:21:14 Is 0 a valid rate?
peah-webrtc 2016/06/27 22:51:47 Good point! Done.
114 old_gain_ = 1.f;
115 gain_change_step_size_ = 0.001f * (48000.f / sample_rate_hz);
116 }
117
118 int GainApplier::Process(float new_gain, AudioBuffer* audio) {
119 int num_saturations = 0;
hlundin-webrtc 2016/06/27 11:21:14 You may want to add RTC_DCHECK_NE(gain_change_step
peah-webrtc 2016/06/27 22:51:47 Good point! Done.
120 if (new_gain != 1.f) {
121 float last_applied_gain = 1.f;
122 for (size_t k = 0; k < audio->num_channels(); ++k) {
123 // TODO(peah): Consider using a faster update rate downwards than upwards.
124 last_applied_gain = ApplyGain(
125 new_gain, old_gain_, gain_change_step_size_,
126 rtc::ArrayView<float>(audio->channels_f()[k], audio->num_frames()));
127 }
128 // TODO(peah): Consider the need for faster gain reduction in case of
129 // excessive saturation.
130 num_saturations = CountSaturations(*audio);
131 LimitToAllowedRange(audio);
132 old_gain_ = last_applied_gain;
133 }
134
135 data_dumper_->DumpRaw("lc_last_applied_gain", 1, &old_gain_);
136
137 return num_saturations;
138 }
139
140 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698