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

Side by Side Diff: webrtc/modules/audio_processing/agc/agc_manager_direct.cc

Issue 2543753006: AGC: Route clipping parameter from webrtc::Config to AGC (Closed)
Patch Set: Fix a typo 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) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 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/agc/agc_manager_direct.h" 11 #include "webrtc/modules/audio_processing/agc/agc_manager_direct.h"
12 12
13 #include <cmath> 13 #include <cmath>
14 14
15 #ifdef WEBRTC_AGC_DEBUG_DUMP 15 #ifdef WEBRTC_AGC_DEBUG_DUMP
16 #include <cstdio> 16 #include <cstdio>
17 #endif 17 #endif
18 18
19 #include "webrtc/base/checks.h" 19 #include "webrtc/base/checks.h"
20 #include "webrtc/modules/audio_processing/agc/gain_map_internal.h" 20 #include "webrtc/modules/audio_processing/agc/gain_map_internal.h"
21 #include "webrtc/modules/audio_processing/gain_control_impl.h" 21 #include "webrtc/modules/audio_processing/gain_control_impl.h"
22 #include "webrtc/modules/include/module_common_types.h" 22 #include "webrtc/modules/include/module_common_types.h"
23 #include "webrtc/system_wrappers/include/logging.h" 23 #include "webrtc/system_wrappers/include/logging.h"
24 #include "webrtc/system_wrappers/include/metrics.h" 24 #include "webrtc/system_wrappers/include/metrics.h"
25 25
26 namespace webrtc { 26 namespace webrtc {
27 27
28 namespace { 28 namespace {
29 29
30 // Lowest the microphone level can be lowered due to clipping.
31 const int kClippedLevelMin = 170;
32 // Amount the microphone level is lowered with every clipping event. 30 // Amount the microphone level is lowered with every clipping event.
33 const int kClippedLevelStep = 15; 31 const int kClippedLevelStep = 15;
34 // Proportion of clipped samples required to declare a clipping event. 32 // Proportion of clipped samples required to declare a clipping event.
35 const float kClippedRatioThreshold = 0.1f; 33 const float kClippedRatioThreshold = 0.1f;
36 // Time in frames to wait after a clipping event before checking again. 34 // Time in frames to wait after a clipping event before checking again.
37 const int kClippedWaitFrames = 300; 35 const int kClippedWaitFrames = 300;
38 36
39 // Amount of error we tolerate in the microphone level (presumably due to OS 37 // Amount of error we tolerate in the microphone level (presumably due to OS
40 // quantization) before we assume the user has manually adjusted the microphone. 38 // quantization) before we assume the user has manually adjusted the microphone.
41 const int kLevelQuantizationSlack = 25; 39 const int kLevelQuantizationSlack = 25;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 } 106 }
109 ~DebugFile() { 107 ~DebugFile() {
110 } 108 }
111 void Write(const int16_t* data, size_t length_samples) { 109 void Write(const int16_t* data, size_t length_samples) {
112 } 110 }
113 #endif // WEBRTC_AGC_DEBUG_DUMP 111 #endif // WEBRTC_AGC_DEBUG_DUMP
114 }; 112 };
115 113
116 AgcManagerDirect::AgcManagerDirect(GainControl* gctrl, 114 AgcManagerDirect::AgcManagerDirect(GainControl* gctrl,
117 VolumeCallbacks* volume_callbacks, 115 VolumeCallbacks* volume_callbacks,
118 int startup_min_level) 116 int startup_min_level,
117 int clipped_level_min)
119 : agc_(new Agc()), 118 : agc_(new Agc()),
120 gctrl_(gctrl), 119 gctrl_(gctrl),
121 volume_callbacks_(volume_callbacks), 120 volume_callbacks_(volume_callbacks),
122 frames_since_clipped_(kClippedWaitFrames), 121 frames_since_clipped_(kClippedWaitFrames),
123 level_(0), 122 level_(0),
124 max_level_(kMaxMicLevel), 123 max_level_(kMaxMicLevel),
125 max_compression_gain_(kMaxCompressionGain), 124 max_compression_gain_(kMaxCompressionGain),
126 target_compression_(kDefaultCompressionGain), 125 target_compression_(kDefaultCompressionGain),
127 compression_(target_compression_), 126 compression_(target_compression_),
128 compression_accumulator_(compression_), 127 compression_accumulator_(compression_),
129 capture_muted_(false), 128 capture_muted_(false),
130 check_volume_on_next_process_(true), // Check at startup. 129 check_volume_on_next_process_(true), // Check at startup.
131 startup_(true), 130 startup_(true),
132 startup_min_level_(ClampLevel(startup_min_level)), 131 startup_min_level_(ClampLevel(startup_min_level)),
132 clipped_level_min_(clipped_level_min),
133 file_preproc_(new DebugFile("agc_preproc.pcm")), 133 file_preproc_(new DebugFile("agc_preproc.pcm")),
134 file_postproc_(new DebugFile("agc_postproc.pcm")) { 134 file_postproc_(new DebugFile("agc_postproc.pcm")) {}
135 }
136 135
137 AgcManagerDirect::AgcManagerDirect(Agc* agc, 136 AgcManagerDirect::AgcManagerDirect(Agc* agc,
138 GainControl* gctrl, 137 GainControl* gctrl,
139 VolumeCallbacks* volume_callbacks, 138 VolumeCallbacks* volume_callbacks,
140 int startup_min_level) 139 int startup_min_level,
140 int clipped_level_min)
141 : agc_(agc), 141 : agc_(agc),
142 gctrl_(gctrl), 142 gctrl_(gctrl),
143 volume_callbacks_(volume_callbacks), 143 volume_callbacks_(volume_callbacks),
144 frames_since_clipped_(kClippedWaitFrames), 144 frames_since_clipped_(kClippedWaitFrames),
145 level_(0), 145 level_(0),
146 max_level_(kMaxMicLevel), 146 max_level_(kMaxMicLevel),
147 max_compression_gain_(kMaxCompressionGain), 147 max_compression_gain_(kMaxCompressionGain),
148 target_compression_(kDefaultCompressionGain), 148 target_compression_(kDefaultCompressionGain),
149 compression_(target_compression_), 149 compression_(target_compression_),
150 compression_accumulator_(compression_), 150 compression_accumulator_(compression_),
151 capture_muted_(false), 151 capture_muted_(false),
152 check_volume_on_next_process_(true), // Check at startup. 152 check_volume_on_next_process_(true), // Check at startup.
153 startup_(true), 153 startup_(true),
154 startup_min_level_(ClampLevel(startup_min_level)), 154 startup_min_level_(ClampLevel(startup_min_level)),
155 clipped_level_min_(clipped_level_min),
155 file_preproc_(new DebugFile("agc_preproc.pcm")), 156 file_preproc_(new DebugFile("agc_preproc.pcm")),
156 file_postproc_(new DebugFile("agc_postproc.pcm")) { 157 file_postproc_(new DebugFile("agc_postproc.pcm")) {}
157 }
158 158
159 AgcManagerDirect::~AgcManagerDirect() {} 159 AgcManagerDirect::~AgcManagerDirect() {}
160 160
161 int AgcManagerDirect::Initialize() { 161 int AgcManagerDirect::Initialize() {
162 max_level_ = kMaxMicLevel; 162 max_level_ = kMaxMicLevel;
163 max_compression_gain_ = kMaxCompressionGain; 163 max_compression_gain_ = kMaxCompressionGain;
164 target_compression_ = kDefaultCompressionGain; 164 target_compression_ = kDefaultCompressionGain;
165 compression_ = target_compression_; 165 compression_ = target_compression_;
166 compression_accumulator_ = compression_; 166 compression_accumulator_ = compression_;
167 capture_muted_ = false; 167 capture_muted_ = false;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 // and enforce a new maximum level, dropped the same amount from the current 211 // and enforce a new maximum level, dropped the same amount from the current
212 // maximum. This harsh treatment is an effort to avoid repeated clipped echo 212 // maximum. This harsh treatment is an effort to avoid repeated clipped echo
213 // events. As compensation for this restriction, the maximum compression 213 // events. As compensation for this restriction, the maximum compression
214 // gain is increased, through SetMaxLevel(). 214 // gain is increased, through SetMaxLevel().
215 float clipped_ratio = agc_->AnalyzePreproc(audio, length); 215 float clipped_ratio = agc_->AnalyzePreproc(audio, length);
216 if (clipped_ratio > kClippedRatioThreshold) { 216 if (clipped_ratio > kClippedRatioThreshold) {
217 LOG(LS_INFO) << "[agc] Clipping detected. clipped_ratio=" 217 LOG(LS_INFO) << "[agc] Clipping detected. clipped_ratio="
218 << clipped_ratio; 218 << clipped_ratio;
219 // Always decrease the maximum level, even if the current level is below 219 // Always decrease the maximum level, even if the current level is below
220 // threshold. 220 // threshold.
221 SetMaxLevel(std::max(kClippedLevelMin, max_level_ - kClippedLevelStep)); 221 SetMaxLevel(std::max(clipped_level_min_, max_level_ - kClippedLevelStep));
222 RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.AgcClippingAdjustmentAllowed", 222 RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.AgcClippingAdjustmentAllowed",
223 level_ - kClippedLevelStep >= kClippedLevelMin); 223 level_ - kClippedLevelStep >= clipped_level_min_);
224 if (level_ > kClippedLevelMin) { 224 if (level_ > clipped_level_min_) {
225 // Don't try to adjust the level if we're already below the limit. As 225 // Don't try to adjust the level if we're already below the limit. As
226 // a consequence, if the user has brought the level above the limit, we 226 // a consequence, if the user has brought the level above the limit, we
227 // will still not react until the postproc updates the level. 227 // will still not react until the postproc updates the level.
228 SetLevel(std::max(kClippedLevelMin, level_ - kClippedLevelStep)); 228 SetLevel(std::max(clipped_level_min_, level_ - kClippedLevelStep));
229 // Reset the AGC since the level has changed. 229 // Reset the AGC since the level has changed.
230 agc_->Reset(); 230 agc_->Reset();
231 } 231 }
232 frames_since_clipped_ = 0; 232 frames_since_clipped_ = 0;
233 } 233 }
234 } 234 }
235 235
236 void AgcManagerDirect::Process(const int16_t* audio, 236 void AgcManagerDirect::Process(const int16_t* audio,
237 size_t length, 237 size_t length,
238 int sample_rate_hz) { 238 int sample_rate_hz) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 } 294 }
295 295
296 volume_callbacks_->SetMicVolume(new_level); 296 volume_callbacks_->SetMicVolume(new_level);
297 LOG(LS_INFO) << "[agc] voe_level=" << voe_level << ", " 297 LOG(LS_INFO) << "[agc] voe_level=" << voe_level << ", "
298 << "level_=" << level_ << ", " 298 << "level_=" << level_ << ", "
299 << "new_level=" << new_level; 299 << "new_level=" << new_level;
300 level_ = new_level; 300 level_ = new_level;
301 } 301 }
302 302
303 void AgcManagerDirect::SetMaxLevel(int level) { 303 void AgcManagerDirect::SetMaxLevel(int level) {
304 RTC_DCHECK_GE(level, kClippedLevelMin); 304 RTC_DCHECK_GE(level, clipped_level_min_);
305 max_level_ = level; 305 max_level_ = level;
306 // Scale the |kSurplusCompressionGain| linearly across the restricted 306 // Scale the |kSurplusCompressionGain| linearly across the restricted
307 // level range. 307 // level range.
308 max_compression_gain_ = kMaxCompressionGain + std::floor( 308 max_compression_gain_ =
309 (1.f * kMaxMicLevel - max_level_) / (kMaxMicLevel - kClippedLevelMin) * 309 kMaxCompressionGain + std::floor((1.f * kMaxMicLevel - max_level_) /
310 kSurplusCompressionGain + 0.5f); 310 (kMaxMicLevel - clipped_level_min_) *
311 kSurplusCompressionGain +
312 0.5f);
311 LOG(LS_INFO) << "[agc] max_level_=" << max_level_ 313 LOG(LS_INFO) << "[agc] max_level_=" << max_level_
312 << ", max_compression_gain_=" << max_compression_gain_; 314 << ", max_compression_gain_=" << max_compression_gain_;
313 } 315 }
314 316
315 void AgcManagerDirect::SetCaptureMuted(bool muted) { 317 void AgcManagerDirect::SetCaptureMuted(bool muted) {
316 if (capture_muted_ == muted) { 318 if (capture_muted_ == muted) {
317 return; 319 return;
318 } 320 }
319 capture_muted_ = muted; 321 capture_muted_ = muted;
320 322
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 compression_ = new_compression; 445 compression_ = new_compression;
444 compression_accumulator_ = new_compression; 446 compression_accumulator_ = new_compression;
445 if (gctrl_->set_compression_gain_db(compression_) != 0) { 447 if (gctrl_->set_compression_gain_db(compression_) != 0) {
446 LOG(LS_ERROR) << "set_compression_gain_db(" << compression_ 448 LOG(LS_ERROR) << "set_compression_gain_db(" << compression_
447 << ") failed."; 449 << ") failed.";
448 } 450 }
449 } 451 }
450 } 452 }
451 453
452 } // namespace webrtc 454 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698