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) { |
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 Loading... | |
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 |
OLD | NEW |