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

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 an assignment error Created 4 years, 5 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) {
28 return std::count_if(in.begin(), in.end(), [](float v) {
aleloi 2016/06/28 09:35:52 Probably the compiler is smart and this is not aff
peah-webrtc 2016/06/28 22:19:37 I'm not an expert on this, but I think it should b
hlundin-webrtc 2016/06/29 08:56:28 I think that in this case it makes no difference.
peah-webrtc 2016/06/29 09:13:53 Acknowledged.
29 return v >= kMaxSampleValue || v <= kMinSampleValue;
30 });
31 }
32
33 int CountSaturations(const AudioBuffer& audio) {
34 int num_saturations = 0;
35 for (size_t k = 0; k < audio.num_channels(); ++k) {
36 num_saturations += CountSaturations(rtc::ArrayView<const float>(
37 audio.channels_const_f()[k], audio.num_frames()));
38 }
39 return num_saturations;
40 }
41
42 void LimitToAllowedRange(rtc::ArrayView<float> x) {
43 for (auto& v : x) {
44 v = std::max(kMinSampleValue, v);
45 v = std::min(kMaxSampleValue, v);
46 }
47 }
48
49 void LimitToAllowedRange(AudioBuffer* audio) {
50 for (size_t k = 0; k < audio->num_channels(); ++k) {
51 LimitToAllowedRange(
52 rtc::ArrayView<float>(audio->channels_f()[k], audio->num_frames()));
53 }
54 }
55
56 float ApplyIncreasingGain(float new_gain,
57 float old_gain,
58 float step_size,
59 rtc::ArrayView<float> x) {
60 RTC_DCHECK_LT(0.f, step_size);
61 float gain = old_gain;
62 for (auto& v : x) {
63 gain = std::min(new_gain, gain + step_size);
aleloi 2016/06/28 09:35:52 Maybe move the gain calculation outside of the loo
peah-webrtc 2016/06/28 22:19:37 I'm not fully sure of what you mean, but the inten
aleloi 2016/06/29 14:11:18 Acknowledged.
64 v *= gain;
65 }
66 return gain;
67 }
68
69 float ApplyDecreasingGain(float new_gain,
70 float old_gain,
71 float step_size,
72 rtc::ArrayView<float> x) {
73 RTC_DCHECK_LT(0.f, step_size);
74 float gain = old_gain;
75 for (auto& v : x) {
76 gain = std::max(new_gain, gain - step_size);
77 v *= gain;
78 }
79 return gain;
80 }
81
82 float ApplyConstantGain(float gain, rtc::ArrayView<float> x) {
83 for (auto& v : x) {
84 v *= gain;
85 }
86
87 return gain;
88 }
89
90 float ApplyGain(float new_gain,
91 float old_gain,
92 float step_size,
93 rtc::ArrayView<float> x) {
94 if (new_gain == old_gain) {
95 return ApplyConstantGain(new_gain, x);
96 } else if (new_gain > old_gain) {
97 return ApplyIncreasingGain(new_gain, old_gain, step_size, x);
98 } else {
99 return ApplyDecreasingGain(new_gain, old_gain, step_size, x);
100 }
101 }
102
103 } // namespace
104
105 GainApplier::GainApplier(ApmDataDumper* data_dumper)
106 : data_dumper_(data_dumper) {}
107
108 void GainApplier::Initialize(int sample_rate_hz) {
109 RTC_DCHECK(sample_rate_hz == AudioProcessing::kSampleRate8kHz ||
110 sample_rate_hz == AudioProcessing::kSampleRate16kHz ||
111 sample_rate_hz == AudioProcessing::kSampleRate32kHz ||
112 sample_rate_hz == AudioProcessing::kSampleRate48kHz);
113 old_gain_ = 1.f;
114 gain_change_step_size_ = 0.001f * (48000.f / sample_rate_hz);
aleloi 2016/06/28 09:35:52 Please define a constant for 0.001f.
peah-webrtc 2016/06/28 22:19:37 That definitely makes sense. Done.
115 }
aleloi 2016/06/28 09:35:52 Do we need both a constructor and an Initialize()
peah-webrtc 2016/06/28 22:19:37 I definitely agree that it would be nicer to do th
aleloi 2016/06/29 14:11:18 Acknowledged.
116
117 int GainApplier::Process(float new_gain, AudioBuffer* audio) {
118 RTC_CHECK_NE(0.f, gain_change_step_size_);
119 int num_saturations = 0;
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