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

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

Powered by Google App Engine
This is Rietveld 408576698