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