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

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

Issue 1768943002: Removed the dependency in GainControlImpl on the ProcessingComponent class (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@RemoveComponentFromAECM_CL
Patch Set: Changes in response to reviewer comments Created 4 years, 9 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
« no previous file with comments | « webrtc/modules/audio_processing/gain_control_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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/gain_control_impl.h" 11 #include "webrtc/modules/audio_processing/gain_control_impl.h"
12 12
13 #include <assert.h> 13 #include "webrtc/base/optional.h"
14
15 #include "webrtc/modules/audio_processing/audio_buffer.h" 14 #include "webrtc/modules/audio_processing/audio_buffer.h"
16 #include "webrtc/modules/audio_processing/agc/legacy/gain_control.h" 15 #include "webrtc/modules/audio_processing/agc/legacy/gain_control.h"
17 16
18 namespace webrtc { 17 namespace webrtc {
19 18
20 typedef void Handle; 19 typedef void Handle;
21 20
22 namespace { 21 namespace {
23 int16_t MapSetting(GainControl::Mode mode) { 22 int16_t MapSetting(GainControl::Mode mode) {
24 switch (mode) { 23 switch (mode) {
25 case GainControl::kAdaptiveAnalog: 24 case GainControl::kAdaptiveAnalog:
26 return kAgcModeAdaptiveAnalog; 25 return kAgcModeAdaptiveAnalog;
27 case GainControl::kAdaptiveDigital: 26 case GainControl::kAdaptiveDigital:
28 return kAgcModeAdaptiveDigital; 27 return kAgcModeAdaptiveDigital;
29 case GainControl::kFixedDigital: 28 case GainControl::kFixedDigital:
30 return kAgcModeFixedDigital; 29 return kAgcModeFixedDigital;
31 } 30 }
32 assert(false); 31 assert(false);
the sun 2016/03/09 21:51:24 RTC_DCHECK
33 return -1; 32 return -1;
34 } 33 }
35 34
36 // Maximum length that a frame of samples can have. 35 // Maximum length that a frame of samples can have.
37 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160; 36 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160;
38 // Maximum number of frames to buffer in the render queue. 37 // Maximum number of frames to buffer in the render queue.
39 // TODO(peah): Decrease this once we properly handle hugely unbalanced 38 // TODO(peah): Decrease this once we properly handle hugely unbalanced
40 // reverse and forward call numbers. 39 // reverse and forward call numbers.
41 static const size_t kMaxNumFramesToBuffer = 100; 40 static const size_t kMaxNumFramesToBuffer = 100;
42 41
43 } // namespace 42 } // namespace
44 43
44 class GainControlImpl::GainController {
45 public:
46 explicit GainController() {
47 state_ = WebRtcAgc_Create();
48 RTC_CHECK(state_);
49 }
50
51 ~GainController() {
52 RTC_DCHECK(state_);
53 WebRtcAgc_Free(state_);
54 }
55
56 Handle* state() {
57 RTC_DCHECK(state_);
58 return state_;
59 }
60
61 void Initialize(int minimum_capture_level,
62 int maximum_capture_level,
63 Mode mode,
64 int sample_rate_hz,
65 int capture_level) {
66 RTC_DCHECK(state_);
67 int error =
68 WebRtcAgc_Init(state_, minimum_capture_level, maximum_capture_level,
69 MapSetting(mode), sample_rate_hz);
70 RTC_DCHECK_EQ(0, error);
71
72 set_capture_level(capture_level);
73 }
74
75 void set_capture_level(int capture_level) {
76 capture_level_ = rtc::Optional<int>(capture_level);
77 }
78
79 int get_capture_level() {
80 RTC_DCHECK(capture_level_);
81 return *capture_level_;
82 }
83
84 private:
85 Handle* state_;
86 // TODO(peah): Remove the optional once the initialization is moved into the
87 // ctor.
88 rtc::Optional<int> capture_level_;
89
90 RTC_DISALLOW_COPY_AND_ASSIGN(GainController);
91 };
92
45 GainControlImpl::GainControlImpl(const AudioProcessing* apm, 93 GainControlImpl::GainControlImpl(const AudioProcessing* apm,
46 rtc::CriticalSection* crit_render, 94 rtc::CriticalSection* crit_render,
47 rtc::CriticalSection* crit_capture) 95 rtc::CriticalSection* crit_capture)
48 : ProcessingComponent(), 96 : apm_(apm),
49 apm_(apm),
50 crit_render_(crit_render), 97 crit_render_(crit_render),
51 crit_capture_(crit_capture), 98 crit_capture_(crit_capture),
52 mode_(kAdaptiveAnalog), 99 mode_(kAdaptiveAnalog),
53 minimum_capture_level_(0), 100 minimum_capture_level_(0),
54 maximum_capture_level_(255), 101 maximum_capture_level_(255),
55 limiter_enabled_(true), 102 limiter_enabled_(true),
56 target_level_dbfs_(3), 103 target_level_dbfs_(3),
57 compression_gain_db_(9), 104 compression_gain_db_(9),
58 analog_capture_level_(0), 105 analog_capture_level_(0),
59 was_analog_level_set_(false), 106 was_analog_level_set_(false),
60 stream_is_saturated_(false), 107 stream_is_saturated_(false),
61 render_queue_element_max_size_(0) { 108 render_queue_element_max_size_(0) {
62 RTC_DCHECK(apm); 109 RTC_DCHECK(apm);
63 RTC_DCHECK(crit_render); 110 RTC_DCHECK(crit_render);
64 RTC_DCHECK(crit_capture); 111 RTC_DCHECK(crit_capture);
65 } 112 }
66 113
67 GainControlImpl::~GainControlImpl() {} 114 GainControlImpl::~GainControlImpl() {}
68 115
69 int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) { 116 int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) {
70 rtc::CritScope cs(crit_render_); 117 rtc::CritScope cs(crit_render_);
71 if (!is_component_enabled()) { 118 if (!enabled_) {
72 return AudioProcessing::kNoError; 119 return AudioProcessing::kNoError;
73 } 120 }
74 121
75 assert(audio->num_frames_per_band() <= 160); 122 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
76 123
77 render_queue_buffer_.resize(0); 124 render_queue_buffer_.resize(0);
78 for (size_t i = 0; i < num_handles(); i++) { 125 for (auto& gain_controller : gain_controllers_) {
79 Handle* my_handle = static_cast<Handle*>(handle(i)); 126 int err = WebRtcAgc_GetAddFarendError(gain_controller->state(),
80 int err = 127 audio->num_frames_per_band());
81 WebRtcAgc_GetAddFarendError(my_handle, audio->num_frames_per_band());
82 128
83 if (err != AudioProcessing::kNoError) 129 if (err != AudioProcessing::kNoError) {
84 return GetHandleError(my_handle); 130 return AudioProcessing::kUnspecifiedError;
131 }
85 132
86 // Buffer the samples in the render queue. 133 // Buffer the samples in the render queue.
87 render_queue_buffer_.insert( 134 render_queue_buffer_.insert(
88 render_queue_buffer_.end(), audio->mixed_low_pass_data(), 135 render_queue_buffer_.end(), audio->mixed_low_pass_data(),
89 (audio->mixed_low_pass_data() + audio->num_frames_per_band())); 136 (audio->mixed_low_pass_data() + audio->num_frames_per_band()));
90 } 137 }
91 138
92 // Insert the samples into the queue. 139 // Insert the samples into the queue.
93 if (!render_signal_queue_->Insert(&render_queue_buffer_)) { 140 if (!render_signal_queue_->Insert(&render_queue_buffer_)) {
94 // The data queue is full and needs to be emptied. 141 // The data queue is full and needs to be emptied.
95 ReadQueuedRenderData(); 142 ReadQueuedRenderData();
96 143
97 // Retry the insert (should always work). 144 // Retry the insert (should always work).
98 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); 145 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true);
99 } 146 }
100 147
101 return AudioProcessing::kNoError; 148 return AudioProcessing::kNoError;
102 } 149 }
103 150
104 // Read chunks of data that were received and queued on the render side from 151 // Read chunks of data that were received and queued on the render side from
105 // a queue. All the data chunks are buffered into the farend signal of the AGC. 152 // a queue. All the data chunks are buffered into the farend signal of the AGC.
106 void GainControlImpl::ReadQueuedRenderData() { 153 void GainControlImpl::ReadQueuedRenderData() {
107 rtc::CritScope cs(crit_capture_); 154 rtc::CritScope cs(crit_capture_);
108 155
109 if (!is_component_enabled()) { 156 if (!enabled_) {
110 return; 157 return;
111 } 158 }
112 159
113 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { 160 while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
114 size_t buffer_index = 0; 161 size_t buffer_index = 0;
115 const size_t num_frames_per_band = 162 const size_t num_frames_per_band =
116 capture_queue_buffer_.size() / num_handles(); 163 capture_queue_buffer_.size() / num_handles_required();
117 for (size_t i = 0; i < num_handles(); i++) { 164 for (auto& gain_controller : gain_controllers_) {
118 Handle* my_handle = static_cast<Handle*>(handle(i)); 165 WebRtcAgc_AddFarend(gain_controller->state(),
119 WebRtcAgc_AddFarend(my_handle, &capture_queue_buffer_[buffer_index], 166 &capture_queue_buffer_[buffer_index],
120 num_frames_per_band); 167 num_frames_per_band);
121 168
122 buffer_index += num_frames_per_band; 169 buffer_index += num_frames_per_band;
123 } 170 }
124 } 171 }
125 } 172 }
126 173
127 int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { 174 int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
128 rtc::CritScope cs(crit_capture_); 175 rtc::CritScope cs(crit_capture_);
129 176
130 if (!is_component_enabled()) { 177 if (!enabled_) {
131 return AudioProcessing::kNoError; 178 return AudioProcessing::kNoError;
132 } 179 }
133 180
134 assert(audio->num_frames_per_band() <= 160); 181 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
135 assert(audio->num_channels() == num_handles()); 182 RTC_DCHECK_EQ(audio->num_channels(), num_handles_required());
136 183 RTC_DCHECK_LE(num_handles_required(), gain_controllers_.size());
137 int err = AudioProcessing::kNoError;
138 184
139 if (mode_ == kAdaptiveAnalog) { 185 if (mode_ == kAdaptiveAnalog) {
140 capture_levels_.assign(num_handles(), analog_capture_level_); 186 int capture_channel = 0;
141 for (size_t i = 0; i < num_handles(); i++) { 187 for (auto& gain_controller : gain_controllers_) {
142 Handle* my_handle = static_cast<Handle*>(handle(i)); 188 gain_controller->set_capture_level(analog_capture_level_);
143 err = WebRtcAgc_AddMic( 189 int err = WebRtcAgc_AddMic(
144 my_handle, 190 gain_controller->state(), audio->split_bands(capture_channel),
145 audio->split_bands(i), 191 audio->num_bands(), audio->num_frames_per_band());
146 audio->num_bands(),
147 audio->num_frames_per_band());
148 192
149 if (err != AudioProcessing::kNoError) { 193 if (err != AudioProcessing::kNoError) {
150 return GetHandleError(my_handle); 194 return AudioProcessing::kUnspecifiedError;
151 } 195 }
196 ++capture_channel;
152 } 197 }
153 } else if (mode_ == kAdaptiveDigital) { 198 } else if (mode_ == kAdaptiveDigital) {
199 int capture_channel = 0;
200 for (auto& gain_controller : gain_controllers_) {
201 int32_t capture_level_out = 0;
202 int err = WebRtcAgc_VirtualMic(
203 gain_controller->state(), audio->split_bands(capture_channel),
204 audio->num_bands(), audio->num_frames_per_band(),
205 analog_capture_level_, &capture_level_out);
154 206
155 for (size_t i = 0; i < num_handles(); i++) { 207 gain_controller->set_capture_level(capture_level_out);
156 Handle* my_handle = static_cast<Handle*>(handle(i));
157 int32_t capture_level_out = 0;
158
159 err = WebRtcAgc_VirtualMic(
160 my_handle,
161 audio->split_bands(i),
162 audio->num_bands(),
163 audio->num_frames_per_band(),
164 analog_capture_level_,
165 &capture_level_out);
166
167 capture_levels_[i] = capture_level_out;
168 208
169 if (err != AudioProcessing::kNoError) { 209 if (err != AudioProcessing::kNoError) {
170 return GetHandleError(my_handle); 210 return AudioProcessing::kUnspecifiedError;
171 } 211 }
172 212 ++capture_channel;
173 } 213 }
174 } 214 }
175 215
176 return AudioProcessing::kNoError; 216 return AudioProcessing::kNoError;
177 } 217 }
178 218
179 int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio) { 219 int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio) {
180 rtc::CritScope cs(crit_capture_); 220 rtc::CritScope cs(crit_capture_);
181 221
182 if (!is_component_enabled()) { 222 if (!enabled_) {
183 return AudioProcessing::kNoError; 223 return AudioProcessing::kNoError;
184 } 224 }
185 225
186 if (mode_ == kAdaptiveAnalog && !was_analog_level_set_) { 226 if (mode_ == kAdaptiveAnalog && !was_analog_level_set_) {
187 return AudioProcessing::kStreamParameterNotSetError; 227 return AudioProcessing::kStreamParameterNotSetError;
188 } 228 }
189 229
190 assert(audio->num_frames_per_band() <= 160); 230 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
191 assert(audio->num_channels() == num_handles()); 231 RTC_DCHECK_EQ(audio->num_channels(), num_handles_required());
192 232
193 stream_is_saturated_ = false; 233 stream_is_saturated_ = false;
194 for (size_t i = 0; i < num_handles(); i++) { 234 int capture_channel = 0;
195 Handle* my_handle = static_cast<Handle*>(handle(i)); 235 for (auto& gain_controller : gain_controllers_) {
196 int32_t capture_level_out = 0; 236 int32_t capture_level_out = 0;
197 uint8_t saturation_warning = 0; 237 uint8_t saturation_warning = 0;
198 238
199 // The call to stream_has_echo() is ok from a deadlock perspective 239 // The call to stream_has_echo() is ok from a deadlock perspective
200 // as the capture lock is allready held. 240 // as the capture lock is allready held.
201 int err = WebRtcAgc_Process( 241 int err = WebRtcAgc_Process(
202 my_handle, 242 gain_controller->state(), audio->split_bands_const(capture_channel),
203 audio->split_bands_const(i), 243 audio->num_bands(), audio->num_frames_per_band(),
204 audio->num_bands(), 244 audio->split_bands(capture_channel),
205 audio->num_frames_per_band(), 245 gain_controller->get_capture_level(), &capture_level_out,
206 audio->split_bands(i), 246 apm_->echo_cancellation()->stream_has_echo(), &saturation_warning);
207 capture_levels_[i],
208 &capture_level_out,
209 apm_->echo_cancellation()->stream_has_echo(),
210 &saturation_warning);
211 247
212 if (err != AudioProcessing::kNoError) { 248 if (err != AudioProcessing::kNoError) {
213 return GetHandleError(my_handle); 249 return AudioProcessing::kUnspecifiedError;
214 } 250 }
215 251
216 capture_levels_[i] = capture_level_out; 252 gain_controller->set_capture_level(capture_level_out);
217 if (saturation_warning == 1) { 253 if (saturation_warning == 1) {
218 stream_is_saturated_ = true; 254 stream_is_saturated_ = true;
219 } 255 }
256
257 ++capture_channel;
220 } 258 }
221 259
222 if (mode_ == kAdaptiveAnalog) { 260 if (mode_ == kAdaptiveAnalog) {
223 // Take the analog level to be the average across the handles. 261 // Take the analog level to be the average across the handles.
224 analog_capture_level_ = 0; 262 analog_capture_level_ = 0;
225 for (size_t i = 0; i < num_handles(); i++) { 263 for (auto& gain_controller : gain_controllers_) {
226 analog_capture_level_ += capture_levels_[i]; 264 analog_capture_level_ += gain_controller->get_capture_level();
227 } 265 }
228 266
229 analog_capture_level_ /= num_handles(); 267 analog_capture_level_ /= num_handles_required();
230 } 268 }
231 269
232 was_analog_level_set_ = false; 270 was_analog_level_set_ = false;
233 return AudioProcessing::kNoError; 271 return AudioProcessing::kNoError;
234 } 272 }
235 273
236 // TODO(ajm): ensure this is called under kAdaptiveAnalog. 274 // TODO(ajm): ensure this is called under kAdaptiveAnalog.
237 int GainControlImpl::set_stream_analog_level(int level) { 275 int GainControlImpl::set_stream_analog_level(int level) {
238 rtc::CritScope cs(crit_capture_); 276 rtc::CritScope cs(crit_capture_);
239 277
(...skipping 10 matching lines...) Expand all
250 rtc::CritScope cs(crit_capture_); 288 rtc::CritScope cs(crit_capture_);
251 // TODO(ajm): enable this assertion? 289 // TODO(ajm): enable this assertion?
252 //assert(mode_ == kAdaptiveAnalog); 290 //assert(mode_ == kAdaptiveAnalog);
253 291
254 return analog_capture_level_; 292 return analog_capture_level_;
255 } 293 }
256 294
257 int GainControlImpl::Enable(bool enable) { 295 int GainControlImpl::Enable(bool enable) {
258 rtc::CritScope cs_render(crit_render_); 296 rtc::CritScope cs_render(crit_render_);
259 rtc::CritScope cs_capture(crit_capture_); 297 rtc::CritScope cs_capture(crit_capture_);
260 return EnableComponent(enable); 298 if (enable && !enabled_) {
299 enabled_ = enable; // Must be set before Initialize() is called.
300 Initialize();
301 } else {
302 enabled_ = enable;
303 }
304 return AudioProcessing::kNoError;
261 } 305 }
262 306
263 bool GainControlImpl::is_enabled() const { 307 bool GainControlImpl::is_enabled() const {
264 rtc::CritScope cs(crit_capture_); 308 rtc::CritScope cs(crit_capture_);
265 return is_component_enabled(); 309 return enabled_;
266 } 310 }
267 311
268 int GainControlImpl::set_mode(Mode mode) { 312 int GainControlImpl::set_mode(Mode mode) {
269 rtc::CritScope cs_render(crit_render_); 313 rtc::CritScope cs_render(crit_render_);
270 rtc::CritScope cs_capture(crit_capture_); 314 rtc::CritScope cs_capture(crit_capture_);
271 if (MapSetting(mode) == -1) { 315 if (MapSetting(mode) == -1) {
272 return AudioProcessing::kBadParameterError; 316 return AudioProcessing::kBadParameterError;
273 } 317 }
274 318
275 mode_ = mode; 319 mode_ = mode;
276 return Initialize(); 320 Initialize();
321 return AudioProcessing::kNoError;
277 } 322 }
278 323
279 GainControl::Mode GainControlImpl::mode() const { 324 GainControl::Mode GainControlImpl::mode() const {
280 rtc::CritScope cs(crit_capture_); 325 rtc::CritScope cs(crit_capture_);
281 return mode_; 326 return mode_;
282 } 327 }
283 328
284 int GainControlImpl::set_analog_level_limits(int minimum, 329 int GainControlImpl::set_analog_level_limits(int minimum,
285 int maximum) { 330 int maximum) {
286 rtc::CritScope cs(crit_capture_); 331 rtc::CritScope cs(crit_capture_);
287 if (minimum < 0) { 332 if (minimum < 0) {
288 return AudioProcessing::kBadParameterError; 333 return AudioProcessing::kBadParameterError;
289 } 334 }
290 335
291 if (maximum > 65535) { 336 if (maximum > 65535) {
292 return AudioProcessing::kBadParameterError; 337 return AudioProcessing::kBadParameterError;
293 } 338 }
294 339
295 if (maximum < minimum) { 340 if (maximum < minimum) {
296 return AudioProcessing::kBadParameterError; 341 return AudioProcessing::kBadParameterError;
297 } 342 }
298 343
299 minimum_capture_level_ = minimum; 344 minimum_capture_level_ = minimum;
300 maximum_capture_level_ = maximum; 345 maximum_capture_level_ = maximum;
301 346
302 return Initialize(); 347 Initialize();
348 return AudioProcessing::kNoError;
303 } 349 }
304 350
305 int GainControlImpl::analog_level_minimum() const { 351 int GainControlImpl::analog_level_minimum() const {
306 rtc::CritScope cs(crit_capture_); 352 rtc::CritScope cs(crit_capture_);
307 return minimum_capture_level_; 353 return minimum_capture_level_;
308 } 354 }
309 355
310 int GainControlImpl::analog_level_maximum() const { 356 int GainControlImpl::analog_level_maximum() const {
311 rtc::CritScope cs(crit_capture_); 357 rtc::CritScope cs(crit_capture_);
312 return maximum_capture_level_; 358 return maximum_capture_level_;
313 } 359 }
314 360
315 bool GainControlImpl::stream_is_saturated() const { 361 bool GainControlImpl::stream_is_saturated() const {
316 rtc::CritScope cs(crit_capture_); 362 rtc::CritScope cs(crit_capture_);
317 return stream_is_saturated_; 363 return stream_is_saturated_;
318 } 364 }
319 365
320 int GainControlImpl::set_target_level_dbfs(int level) { 366 int GainControlImpl::set_target_level_dbfs(int level) {
321 rtc::CritScope cs(crit_capture_);
322 if (level > 31 || level < 0) { 367 if (level > 31 || level < 0) {
323 return AudioProcessing::kBadParameterError; 368 return AudioProcessing::kBadParameterError;
324 } 369 }
325 370
the sun 2016/03/09 21:51:24 nit: delete blank line
peah-webrtc 2016/03/11 05:03:56 Done.
326 target_level_dbfs_ = level; 371 {
372 rtc::CritScope cs(crit_capture_);
373 target_level_dbfs_ = level;
374 }
327 return Configure(); 375 return Configure();
328 } 376 }
329 377
330 int GainControlImpl::target_level_dbfs() const { 378 int GainControlImpl::target_level_dbfs() const {
331 rtc::CritScope cs(crit_capture_); 379 rtc::CritScope cs(crit_capture_);
332 return target_level_dbfs_; 380 return target_level_dbfs_;
333 } 381 }
334 382
335 int GainControlImpl::set_compression_gain_db(int gain) { 383 int GainControlImpl::set_compression_gain_db(int gain) {
336 rtc::CritScope cs(crit_capture_);
337 if (gain < 0 || gain > 90) { 384 if (gain < 0 || gain > 90) {
338 return AudioProcessing::kBadParameterError; 385 return AudioProcessing::kBadParameterError;
339 } 386 }
340 387 {
341 compression_gain_db_ = gain; 388 rtc::CritScope cs(crit_capture_);
389 compression_gain_db_ = gain;
390 }
342 return Configure(); 391 return Configure();
343 } 392 }
344 393
345 int GainControlImpl::compression_gain_db() const { 394 int GainControlImpl::compression_gain_db() const {
346 rtc::CritScope cs(crit_capture_); 395 rtc::CritScope cs(crit_capture_);
347 return compression_gain_db_; 396 return compression_gain_db_;
348 } 397 }
349 398
350 int GainControlImpl::enable_limiter(bool enable) { 399 int GainControlImpl::enable_limiter(bool enable) {
351 rtc::CritScope cs(crit_capture_); 400 {
352 limiter_enabled_ = enable; 401 rtc::CritScope cs(crit_capture_);
402 limiter_enabled_ = enable;
403 }
353 return Configure(); 404 return Configure();
354 } 405 }
355 406
356 bool GainControlImpl::is_limiter_enabled() const { 407 bool GainControlImpl::is_limiter_enabled() const {
357 rtc::CritScope cs(crit_capture_); 408 rtc::CritScope cs(crit_capture_);
358 return limiter_enabled_; 409 return limiter_enabled_;
359 } 410 }
360 411
361 int GainControlImpl::Initialize() { 412 void GainControlImpl::Initialize() {
362 int err = ProcessingComponent::Initialize(); 413 rtc::CritScope cs_render(crit_render_);
363 if (err != AudioProcessing::kNoError || !is_component_enabled()) { 414 rtc::CritScope cs_capture(crit_capture_);
364 return err; 415 if (!enabled_) {
416 return;
365 } 417 }
366 418
419 int sample_rate_hz = apm_->proc_sample_rate_hz();
420 gain_controllers_.resize(num_handles_required());
421 for (auto& gain_controller : gain_controllers_) {
422 if (!gain_controller) {
423 gain_controller.reset(new GainController());
424 }
425 gain_controller->Initialize(minimum_capture_level_, maximum_capture_level_,
426 mode_, sample_rate_hz, analog_capture_level_);
427 }
428
429 Configure();
430
367 AllocateRenderQueue(); 431 AllocateRenderQueue();
368
369 rtc::CritScope cs_capture(crit_capture_);
370 const int n = num_handles();
371 RTC_CHECK_GE(n, 0) << "Bad number of handles: " << n;
372
373 capture_levels_.assign(n, analog_capture_level_);
374 return AudioProcessing::kNoError;
375 } 432 }
376 433
377 void GainControlImpl::AllocateRenderQueue() { 434 void GainControlImpl::AllocateRenderQueue() {
378 const size_t new_render_queue_element_max_size = 435 const size_t new_render_queue_element_max_size = std::max<size_t>(
379 std::max<size_t>(static_cast<size_t>(1), 436 static_cast<size_t>(1),
380 kMaxAllowedValuesOfSamplesPerFrame * num_handles()); 437 kMaxAllowedValuesOfSamplesPerFrame * num_handles_required());
381 438
382 rtc::CritScope cs_render(crit_render_); 439 rtc::CritScope cs_render(crit_render_);
383 rtc::CritScope cs_capture(crit_capture_); 440 rtc::CritScope cs_capture(crit_capture_);
384 441
385 if (render_queue_element_max_size_ < new_render_queue_element_max_size) { 442 if (render_queue_element_max_size_ < new_render_queue_element_max_size) {
386 render_queue_element_max_size_ = new_render_queue_element_max_size; 443 render_queue_element_max_size_ = new_render_queue_element_max_size;
387 std::vector<int16_t> template_queue_element(render_queue_element_max_size_); 444 std::vector<int16_t> template_queue_element(render_queue_element_max_size_);
388 445
389 render_signal_queue_.reset( 446 render_signal_queue_.reset(
390 new SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>( 447 new SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>(
391 kMaxNumFramesToBuffer, template_queue_element, 448 kMaxNumFramesToBuffer, template_queue_element,
392 RenderQueueItemVerifier<int16_t>(render_queue_element_max_size_))); 449 RenderQueueItemVerifier<int16_t>(render_queue_element_max_size_)));
393 450
394 render_queue_buffer_.resize(render_queue_element_max_size_); 451 render_queue_buffer_.resize(render_queue_element_max_size_);
395 capture_queue_buffer_.resize(render_queue_element_max_size_); 452 capture_queue_buffer_.resize(render_queue_element_max_size_);
396 } else { 453 } else {
397 render_signal_queue_->Clear(); 454 render_signal_queue_->Clear();
398 } 455 }
399 } 456 }
400 457
401 void* GainControlImpl::CreateHandle() const { 458 int GainControlImpl::Configure() {
402 return WebRtcAgc_Create();
403 }
404
405 void GainControlImpl::DestroyHandle(void* handle) const {
406 WebRtcAgc_Free(static_cast<Handle*>(handle));
407 }
408
409 int GainControlImpl::InitializeHandle(void* handle) const {
410 rtc::CritScope cs_render(crit_render_);
411 rtc::CritScope cs_capture(crit_capture_);
412
413 return WebRtcAgc_Init(static_cast<Handle*>(handle),
414 minimum_capture_level_,
415 maximum_capture_level_,
416 MapSetting(mode_),
417 apm_->proc_sample_rate_hz());
418 }
419
420 int GainControlImpl::ConfigureHandle(void* handle) const {
421 rtc::CritScope cs_render(crit_render_); 459 rtc::CritScope cs_render(crit_render_);
422 rtc::CritScope cs_capture(crit_capture_); 460 rtc::CritScope cs_capture(crit_capture_);
423 WebRtcAgcConfig config; 461 WebRtcAgcConfig config;
424 // TODO(ajm): Flip the sign here (since AGC expects a positive value) if we 462 // TODO(ajm): Flip the sign here (since AGC expects a positive value) if we
425 // change the interface. 463 // change the interface.
426 //assert(target_level_dbfs_ <= 0); 464 //assert(target_level_dbfs_ <= 0);
427 //config.targetLevelDbfs = static_cast<int16_t>(-target_level_dbfs_); 465 //config.targetLevelDbfs = static_cast<int16_t>(-target_level_dbfs_);
428 config.targetLevelDbfs = static_cast<int16_t>(target_level_dbfs_); 466 config.targetLevelDbfs = static_cast<int16_t>(target_level_dbfs_);
429 config.compressionGaindB = 467 config.compressionGaindB =
430 static_cast<int16_t>(compression_gain_db_); 468 static_cast<int16_t>(compression_gain_db_);
431 config.limiterEnable = limiter_enabled_; 469 config.limiterEnable = limiter_enabled_;
432 470
433 return WebRtcAgc_set_config(static_cast<Handle*>(handle), config); 471 int error = AudioProcessing::kNoError;
472 for (auto& gain_controller : gain_controllers_) {
473 const int handle_error =
474 WebRtcAgc_set_config(gain_controller->state(), config);
475 if (handle_error != AudioProcessing::kNoError) {
476 error = handle_error;
477 }
478 }
479 return error;
434 } 480 }
435 481
436 size_t GainControlImpl::num_handles_required() const { 482 size_t GainControlImpl::num_handles_required() const {
437 // Not locked as it only relies on APM public API which is threadsafe. 483 // Not locked as it only relies on APM public API which is threadsafe.
438 return apm_->num_proc_channels(); 484 return apm_->num_proc_channels();
439 } 485 }
440
441 int GainControlImpl::GetHandleError(void* handle) const {
442 // The AGC has no get_error() function.
443 // (Despite listing errors in its interface...)
444 assert(handle != NULL);
445 return AudioProcessing::kUnspecifiedError;
446 }
447 } // namespace webrtc 486 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/gain_control_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698