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/echo_cancellation_impl.h" | 11 #include "webrtc/modules/audio_processing/echo_cancellation_impl.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 #include <string.h> | 14 #include <string.h> |
15 | 15 |
16 extern "C" { | 16 extern "C" { |
17 #include "webrtc/modules/audio_processing/aec/aec_core.h" | 17 #include "webrtc/modules/audio_processing/aec/aec_core.h" |
18 } | 18 } |
19 #include "webrtc/base/criticalsection.h" | |
19 #include "webrtc/modules/audio_processing/aec/include/echo_cancellation.h" | 20 #include "webrtc/modules/audio_processing/aec/include/echo_cancellation.h" |
20 #include "webrtc/modules/audio_processing/audio_buffer.h" | 21 #include "webrtc/modules/audio_processing/audio_buffer.h" |
21 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
22 | 22 |
23 namespace webrtc { | 23 namespace webrtc { |
24 | 24 |
25 typedef void Handle; | 25 typedef void Handle; |
26 | 26 |
27 namespace { | 27 namespace { |
28 int16_t MapSetting(EchoCancellation::SuppressionLevel level) { | 28 int16_t MapSetting(EchoCancellation::SuppressionLevel level) { |
29 switch (level) { | 29 switch (level) { |
30 case EchoCancellation::kLowSuppression: | 30 case EchoCancellation::kLowSuppression: |
31 return kAecNlpConservative; | 31 return kAecNlpConservative; |
(...skipping 21 matching lines...) Expand all Loading... | |
53 return AudioProcessing::kUnspecifiedError; | 53 return AudioProcessing::kUnspecifiedError; |
54 } | 54 } |
55 } | 55 } |
56 } // namespace | 56 } // namespace |
57 | 57 |
58 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame1; | 58 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame1; |
59 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame2; | 59 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame2; |
60 | 60 |
61 EchoCancellationImpl::EchoCancellationImpl( | 61 EchoCancellationImpl::EchoCancellationImpl( |
62 const AudioProcessing* apm, | 62 const AudioProcessing* apm, |
63 CriticalSectionWrapper* crit, | 63 rtc::CriticalSection* crit_render, |
64 rtc::CriticalSection* crit_capture, | |
64 rtc::ThreadChecker* render_thread_checker) | 65 rtc::ThreadChecker* render_thread_checker) |
65 : ProcessingComponent(), | 66 : ProcessingComponent(), |
66 apm_(apm), | 67 apm_(apm), |
67 crit_(crit), | 68 crit_render_(crit_render), |
69 crit_capture_(crit_capture), | |
68 render_thread_checker_(render_thread_checker), | 70 render_thread_checker_(render_thread_checker), |
69 drift_compensation_enabled_(false), | 71 drift_compensation_enabled_(false), |
70 metrics_enabled_(false), | 72 metrics_enabled_(false), |
71 suppression_level_(kModerateSuppression), | 73 suppression_level_(kModerateSuppression), |
72 stream_drift_samples_(0), | 74 stream_drift_samples_(0), |
73 was_stream_drift_set_(false), | 75 was_stream_drift_set_(false), |
74 stream_has_echo_(false), | 76 stream_has_echo_(false), |
75 delay_logging_enabled_(false), | 77 delay_logging_enabled_(false), |
76 extended_filter_enabled_(false), | 78 extended_filter_enabled_(false), |
77 delay_agnostic_enabled_(false), | 79 delay_agnostic_enabled_(false), |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 } | 111 } |
110 | 112 |
111 // Buffer the samples in the render queue. | 113 // Buffer the samples in the render queue. |
112 render_queue_buffer_.insert(render_queue_buffer_.end(), | 114 render_queue_buffer_.insert(render_queue_buffer_.end(), |
113 audio->split_bands_const_f(j)[kBand0To8kHz], | 115 audio->split_bands_const_f(j)[kBand0To8kHz], |
114 (audio->split_bands_const_f(j)[kBand0To8kHz] + | 116 (audio->split_bands_const_f(j)[kBand0To8kHz] + |
115 audio->num_frames_per_band())); | 117 audio->num_frames_per_band())); |
116 } | 118 } |
117 } | 119 } |
118 | 120 |
119 // Check of success is temporarily disabled as it breaks a unit test. | 121 // Insert the samples into the queue. |
120 // TODO(peah): Will be fixed in the next CL. | 122 bool success = render_signal_queue_->Insert(&render_queue_buffer_); |
hlundin-webrtc
2015/11/05 16:11:22
You don't need success.
if (!render_signal_queue_-
peah-webrtc
2015/11/06 09:54:32
Done.
| |
121 (void)render_signal_queue_->Insert(&render_queue_buffer_); | 123 if (!success) { |
124 // The data queue is full and needs to be emptied. | |
125 { | |
126 rtc::CritScope cs_capture(crit_capture_); | |
127 ReadQueuedRenderData(); | |
128 } | |
129 | |
130 // Retry the insert (should always work). | |
131 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); | |
132 } | |
122 | 133 |
123 return apm_->kNoError; | 134 return apm_->kNoError; |
124 } | 135 } |
125 | 136 |
126 // Read chunks of data that were received and queued on the render side from | 137 // Read chunks of data that were received and queued on the render side from |
127 // a queue. All the data chunks are buffered into the farend signal of the AEC. | 138 // a queue. All the data chunks are buffered into the farend signal of the AEC. |
128 void EchoCancellationImpl::ReadQueuedRenderData() { | 139 void EchoCancellationImpl::ReadQueuedRenderData() { |
129 if (!is_component_enabled()) { | 140 if (!is_component_enabled()) { |
130 return; | 141 return; |
131 } | 142 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
203 | 214 |
204 handle_index++; | 215 handle_index++; |
205 } | 216 } |
206 } | 217 } |
207 | 218 |
208 was_stream_drift_set_ = false; | 219 was_stream_drift_set_ = false; |
209 return apm_->kNoError; | 220 return apm_->kNoError; |
210 } | 221 } |
211 | 222 |
212 int EchoCancellationImpl::Enable(bool enable) { | 223 int EchoCancellationImpl::Enable(bool enable) { |
213 CriticalSectionScoped crit_scoped(crit_); | 224 // Run in a single-threaded manner. |
225 rtc::CritScope cs_render(crit_render_); | |
226 rtc::CritScope cs_capture(crit_capture_); | |
214 // Ensure AEC and AECM are not both enabled. | 227 // Ensure AEC and AECM are not both enabled. |
215 if (enable && apm_->echo_control_mobile()->is_enabled()) { | 228 if (enable && apm_->echo_control_mobile()->is_enabled()) { |
216 return apm_->kBadParameterError; | 229 return apm_->kBadParameterError; |
217 } | 230 } |
218 | 231 |
219 return EnableComponent(enable); | 232 return EnableComponent(enable); |
220 } | 233 } |
221 | 234 |
222 bool EchoCancellationImpl::is_enabled() const { | 235 bool EchoCancellationImpl::is_enabled() const { |
236 rtc::CritScope cs(crit_capture_); | |
223 return is_component_enabled(); | 237 return is_component_enabled(); |
224 } | 238 } |
225 | 239 |
226 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) { | 240 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) { |
227 CriticalSectionScoped crit_scoped(crit_); | 241 rtc::CritScope cs(crit_capture_); |
228 if (MapSetting(level) == -1) { | 242 if (MapSetting(level) == -1) { |
229 return apm_->kBadParameterError; | 243 return apm_->kBadParameterError; |
230 } | 244 } |
231 | 245 |
232 suppression_level_ = level; | 246 suppression_level_ = level; |
233 return Configure(); | 247 return Configure(); |
234 } | 248 } |
235 | 249 |
236 EchoCancellation::SuppressionLevel EchoCancellationImpl::suppression_level() | 250 EchoCancellation::SuppressionLevel EchoCancellationImpl::suppression_level() |
237 const { | 251 const { |
252 rtc::CritScope cs(crit_capture_); | |
238 return suppression_level_; | 253 return suppression_level_; |
239 } | 254 } |
240 | 255 |
241 int EchoCancellationImpl::enable_drift_compensation(bool enable) { | 256 int EchoCancellationImpl::enable_drift_compensation(bool enable) { |
242 CriticalSectionScoped crit_scoped(crit_); | 257 rtc::CritScope cs(crit_capture_); |
243 drift_compensation_enabled_ = enable; | 258 drift_compensation_enabled_ = enable; |
244 return Configure(); | 259 return Configure(); |
245 } | 260 } |
246 | 261 |
247 bool EchoCancellationImpl::is_drift_compensation_enabled() const { | 262 bool EchoCancellationImpl::is_drift_compensation_enabled() const { |
263 rtc::CritScope cs(crit_capture_); | |
248 return drift_compensation_enabled_; | 264 return drift_compensation_enabled_; |
249 } | 265 } |
250 | 266 |
251 void EchoCancellationImpl::set_stream_drift_samples(int drift) { | 267 void EchoCancellationImpl::set_stream_drift_samples(int drift) { |
268 rtc::CritScope cs(crit_capture_); | |
252 was_stream_drift_set_ = true; | 269 was_stream_drift_set_ = true; |
253 stream_drift_samples_ = drift; | 270 stream_drift_samples_ = drift; |
254 } | 271 } |
255 | 272 |
256 int EchoCancellationImpl::stream_drift_samples() const { | 273 int EchoCancellationImpl::stream_drift_samples() const { |
274 rtc::CritScope cs(crit_capture_); | |
257 return stream_drift_samples_; | 275 return stream_drift_samples_; |
258 } | 276 } |
259 | 277 |
260 int EchoCancellationImpl::enable_metrics(bool enable) { | 278 int EchoCancellationImpl::enable_metrics(bool enable) { |
261 CriticalSectionScoped crit_scoped(crit_); | 279 rtc::CritScope cs(crit_capture_); |
262 metrics_enabled_ = enable; | 280 metrics_enabled_ = enable; |
263 return Configure(); | 281 return Configure(); |
264 } | 282 } |
265 | 283 |
266 bool EchoCancellationImpl::are_metrics_enabled() const { | 284 bool EchoCancellationImpl::are_metrics_enabled() const { |
285 rtc::CritScope cs(crit_capture_); | |
267 return metrics_enabled_; | 286 return metrics_enabled_; |
268 } | 287 } |
269 | 288 |
270 // TODO(ajm): we currently just use the metrics from the first AEC. Think more | 289 // TODO(ajm): we currently just use the metrics from the first AEC. Think more |
271 // aboue the best way to extend this to multi-channel. | 290 // aboue the best way to extend this to multi-channel. |
272 int EchoCancellationImpl::GetMetrics(Metrics* metrics) { | 291 int EchoCancellationImpl::GetMetrics(Metrics* metrics) { |
273 CriticalSectionScoped crit_scoped(crit_); | 292 rtc::CritScope cs(crit_capture_); |
274 if (metrics == NULL) { | 293 if (metrics == NULL) { |
275 return apm_->kNullPointerError; | 294 return apm_->kNullPointerError; |
276 } | 295 } |
277 | 296 |
278 if (!is_component_enabled() || !metrics_enabled_) { | 297 if (!is_component_enabled() || !metrics_enabled_) { |
279 return apm_->kNotEnabledError; | 298 return apm_->kNotEnabledError; |
280 } | 299 } |
281 | 300 |
282 AecMetrics my_metrics; | 301 AecMetrics my_metrics; |
283 memset(&my_metrics, 0, sizeof(my_metrics)); | 302 memset(&my_metrics, 0, sizeof(my_metrics)); |
(...skipping 22 matching lines...) Expand all Loading... | |
306 | 325 |
307 metrics->a_nlp.instant = my_metrics.aNlp.instant; | 326 metrics->a_nlp.instant = my_metrics.aNlp.instant; |
308 metrics->a_nlp.average = my_metrics.aNlp.average; | 327 metrics->a_nlp.average = my_metrics.aNlp.average; |
309 metrics->a_nlp.maximum = my_metrics.aNlp.max; | 328 metrics->a_nlp.maximum = my_metrics.aNlp.max; |
310 metrics->a_nlp.minimum = my_metrics.aNlp.min; | 329 metrics->a_nlp.minimum = my_metrics.aNlp.min; |
311 | 330 |
312 return apm_->kNoError; | 331 return apm_->kNoError; |
313 } | 332 } |
314 | 333 |
315 bool EchoCancellationImpl::stream_has_echo() const { | 334 bool EchoCancellationImpl::stream_has_echo() const { |
316 return stream_has_echo_; | 335 // This is called both from within and from outside of APM, with and |
336 // without locks set. Hence the conditional lock handling below. | |
337 bool stream_has_echo; | |
338 if (crit_capture_->TryEnter()) { | |
hlundin-webrtc
2015/11/05 16:11:22
I don't understand this code, but I wonder if rtc:
peah-webrtc
2015/11/06 09:54:32
Sounds like that! Thanks!
Done.
| |
339 stream_has_echo = stream_has_echo_; | |
340 crit_capture_->Leave(); | |
341 } else { | |
342 stream_has_echo = stream_has_echo_; | |
343 } | |
344 return stream_has_echo; | |
317 } | 345 } |
318 | 346 |
319 int EchoCancellationImpl::enable_delay_logging(bool enable) { | 347 int EchoCancellationImpl::enable_delay_logging(bool enable) { |
320 CriticalSectionScoped crit_scoped(crit_); | 348 rtc::CritScope cs(crit_capture_); |
321 delay_logging_enabled_ = enable; | 349 delay_logging_enabled_ = enable; |
322 return Configure(); | 350 return Configure(); |
323 } | 351 } |
324 | 352 |
325 bool EchoCancellationImpl::is_delay_logging_enabled() const { | 353 bool EchoCancellationImpl::is_delay_logging_enabled() const { |
354 rtc::CritScope cs(crit_capture_); | |
326 return delay_logging_enabled_; | 355 return delay_logging_enabled_; |
327 } | 356 } |
328 | 357 |
329 bool EchoCancellationImpl::is_delay_agnostic_enabled() const { | 358 bool EchoCancellationImpl::is_delay_agnostic_enabled() const { |
359 // Only called from within APM, hence no locking is needed. | |
330 return delay_agnostic_enabled_; | 360 return delay_agnostic_enabled_; |
331 } | 361 } |
332 | 362 |
333 bool EchoCancellationImpl::is_extended_filter_enabled() const { | 363 bool EchoCancellationImpl::is_extended_filter_enabled() const { |
364 // Only called from within APM, hence no locking is needed. | |
334 return extended_filter_enabled_; | 365 return extended_filter_enabled_; |
335 } | 366 } |
336 | 367 |
337 // TODO(bjornv): How should we handle the multi-channel case? | 368 // TODO(bjornv): How should we handle the multi-channel case? |
338 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std) { | 369 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std) { |
370 rtc::CritScope cs(crit_capture_); | |
339 float fraction_poor_delays = 0; | 371 float fraction_poor_delays = 0; |
340 return GetDelayMetrics(median, std, &fraction_poor_delays); | 372 return GetDelayMetrics(median, std, &fraction_poor_delays); |
341 } | 373 } |
342 | 374 |
343 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std, | 375 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std, |
344 float* fraction_poor_delays) { | 376 float* fraction_poor_delays) { |
345 CriticalSectionScoped crit_scoped(crit_); | 377 rtc::CritScope cs(crit_capture_); |
346 if (median == NULL) { | 378 if (median == NULL) { |
347 return apm_->kNullPointerError; | 379 return apm_->kNullPointerError; |
348 } | 380 } |
349 if (std == NULL) { | 381 if (std == NULL) { |
350 return apm_->kNullPointerError; | 382 return apm_->kNullPointerError; |
351 } | 383 } |
352 | 384 |
353 if (!is_component_enabled() || !delay_logging_enabled_) { | 385 if (!is_component_enabled() || !delay_logging_enabled_) { |
354 return apm_->kNotEnabledError; | 386 return apm_->kNotEnabledError; |
355 } | 387 } |
356 | 388 |
357 Handle* my_handle = static_cast<Handle*>(handle(0)); | 389 Handle* my_handle = static_cast<Handle*>(handle(0)); |
358 const int err = | 390 const int err = |
359 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays); | 391 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays); |
360 if (err != apm_->kNoError) { | 392 if (err != apm_->kNoError) { |
361 return MapError(err); | 393 return MapError(err); |
362 } | 394 } |
363 | 395 |
364 return apm_->kNoError; | 396 return apm_->kNoError; |
365 } | 397 } |
366 | 398 |
367 struct AecCore* EchoCancellationImpl::aec_core() const { | 399 struct AecCore* EchoCancellationImpl::aec_core() const { |
368 CriticalSectionScoped crit_scoped(crit_); | 400 // Only called from within APM, hence no locking is needed. |
369 if (!is_component_enabled()) { | 401 if (!is_component_enabled()) { |
370 return NULL; | 402 return NULL; |
371 } | 403 } |
372 Handle* my_handle = static_cast<Handle*>(handle(0)); | 404 Handle* my_handle = static_cast<Handle*>(handle(0)); |
373 return WebRtcAec_aec_core(my_handle); | 405 return WebRtcAec_aec_core(my_handle); |
374 } | 406 } |
375 | 407 |
376 int EchoCancellationImpl::Initialize() { | 408 int EchoCancellationImpl::Initialize() { |
409 // Only called from within APM, hence no locking is needed. | |
377 int err = ProcessingComponent::Initialize(); | 410 int err = ProcessingComponent::Initialize(); |
378 if (err != apm_->kNoError || !is_component_enabled()) { | 411 if (err != apm_->kNoError || !is_component_enabled()) { |
379 return err; | 412 return err; |
380 } | 413 } |
381 | 414 |
382 AllocateRenderQueue(); | 415 AllocateRenderQueue(); |
383 | 416 |
384 return apm_->kNoError; | 417 return apm_->kNoError; |
385 } | 418 } |
386 | 419 |
387 void EchoCancellationImpl::AllocateRenderQueue() { | 420 void EchoCancellationImpl::AllocateRenderQueue() { |
421 // Only called from within APM, hence no locking is needed. | |
388 const size_t max_frame_size = std::max(kAllowedValuesOfSamplesPerFrame1, | 422 const size_t max_frame_size = std::max(kAllowedValuesOfSamplesPerFrame1, |
389 kAllowedValuesOfSamplesPerFrame2); | 423 kAllowedValuesOfSamplesPerFrame2); |
390 | 424 |
391 const size_t new_render_queue_element_max_size = | 425 const size_t new_render_queue_element_max_size = |
392 std::max(1UL, max_frame_size * num_handles_required()); | 426 std::max(1UL, max_frame_size * num_handles_required()); |
393 | 427 |
394 // Reallocate the queue if the queue item size is too small to fit the | 428 // Reallocate the queue if the queue item size is too small to fit the |
395 // data to put in the queue. | 429 // data to put in the queue. |
396 if (new_render_queue_element_max_size > render_queue_element_max_size_) { | 430 if (new_render_queue_element_max_size > render_queue_element_max_size_) { |
397 render_queue_element_max_size_ = new_render_queue_element_max_size; | 431 render_queue_element_max_size_ = new_render_queue_element_max_size; |
398 | 432 |
399 std::vector<float> template_queue_element(render_queue_element_max_size_); | 433 std::vector<float> template_queue_element(render_queue_element_max_size_); |
400 | 434 |
401 render_signal_queue_.reset( | 435 render_signal_queue_.reset( |
402 new SwapQueue<std::vector<float>, AecRenderQueueItemVerifier>( | 436 new SwapQueue<std::vector<float>, AecRenderQueueItemVerifier>( |
403 kMaxNumFramesToBuffer, | 437 kMaxNumFramesToBuffer, |
404 AecRenderQueueItemVerifier(render_queue_element_max_size_), | 438 AecRenderQueueItemVerifier(render_queue_element_max_size_), |
405 template_queue_element)); | 439 template_queue_element)); |
406 } else { | 440 } else { |
407 render_signal_queue_->Clear(); | 441 render_signal_queue_->Clear(); |
408 } | 442 } |
409 | 443 |
410 render_queue_buffer_.resize(new_render_queue_element_max_size); | 444 render_queue_buffer_.resize(new_render_queue_element_max_size); |
411 capture_queue_buffer_.resize(new_render_queue_element_max_size); | 445 capture_queue_buffer_.resize(new_render_queue_element_max_size); |
412 } | 446 } |
413 | 447 |
414 void EchoCancellationImpl::SetExtraOptions(const Config& config) { | 448 void EchoCancellationImpl::SetExtraOptions(const Config& config) { |
449 // This is called both from within and from outside of APM, with and | |
450 // without locks set. Hence the conditional lock handling below. | |
451 bool locked_locally = crit_capture_->TryEnter(); | |
415 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; | 452 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; |
416 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; | 453 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; |
417 Configure(); | 454 Configure(); |
455 if (locked_locally) { | |
456 crit_capture_->Leave(); | |
457 } | |
418 } | 458 } |
419 | 459 |
420 void* EchoCancellationImpl::CreateHandle() const { | 460 void* EchoCancellationImpl::CreateHandle() const { |
461 // Only called from within APM, hence no locking is needed. | |
421 return WebRtcAec_Create(); | 462 return WebRtcAec_Create(); |
422 } | 463 } |
423 | 464 |
424 void EchoCancellationImpl::DestroyHandle(void* handle) const { | 465 void EchoCancellationImpl::DestroyHandle(void* handle) const { |
466 // Only called from within APM, hence no locking is needed. | |
425 assert(handle != NULL); | 467 assert(handle != NULL); |
426 WebRtcAec_Free(static_cast<Handle*>(handle)); | 468 WebRtcAec_Free(static_cast<Handle*>(handle)); |
427 } | 469 } |
428 | 470 |
429 int EchoCancellationImpl::InitializeHandle(void* handle) const { | 471 int EchoCancellationImpl::InitializeHandle(void* handle) const { |
472 // Only called from within APM, hence no locking is needed. | |
430 assert(handle != NULL); | 473 assert(handle != NULL); |
431 // TODO(ajm): Drift compensation is disabled in practice. If restored, it | 474 // TODO(ajm): Drift compensation is disabled in practice. If restored, it |
432 // should be managed internally and not depend on the hardware sample rate. | 475 // should be managed internally and not depend on the hardware sample rate. |
433 // For now, just hardcode a 48 kHz value. | 476 // For now, just hardcode a 48 kHz value. |
434 return WebRtcAec_Init(static_cast<Handle*>(handle), | 477 return WebRtcAec_Init(static_cast<Handle*>(handle), |
435 apm_->proc_sample_rate_hz(), | 478 apm_->proc_sample_rate_hz(), |
436 48000); | 479 48000); |
437 } | 480 } |
438 | 481 |
439 int EchoCancellationImpl::ConfigureHandle(void* handle) const { | 482 int EchoCancellationImpl::ConfigureHandle(void* handle) const { |
483 // Only called from within APM, hence no locking is needed. | |
440 assert(handle != NULL); | 484 assert(handle != NULL); |
441 AecConfig config; | 485 AecConfig config; |
442 config.metricsMode = metrics_enabled_; | 486 config.metricsMode = metrics_enabled_; |
443 config.nlpMode = MapSetting(suppression_level_); | 487 config.nlpMode = MapSetting(suppression_level_); |
444 config.skewMode = drift_compensation_enabled_; | 488 config.skewMode = drift_compensation_enabled_; |
445 config.delay_logging = delay_logging_enabled_; | 489 config.delay_logging = delay_logging_enabled_; |
446 | 490 |
447 WebRtcAec_enable_extended_filter( | 491 WebRtcAec_enable_extended_filter( |
448 WebRtcAec_aec_core(static_cast<Handle*>(handle)), | 492 WebRtcAec_aec_core(static_cast<Handle*>(handle)), |
449 extended_filter_enabled_ ? 1 : 0); | 493 extended_filter_enabled_ ? 1 : 0); |
450 WebRtcAec_enable_delay_agnostic( | 494 WebRtcAec_enable_delay_agnostic( |
451 WebRtcAec_aec_core(static_cast<Handle*>(handle)), | 495 WebRtcAec_aec_core(static_cast<Handle*>(handle)), |
452 delay_agnostic_enabled_ ? 1 : 0); | 496 delay_agnostic_enabled_ ? 1 : 0); |
453 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); | 497 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); |
454 } | 498 } |
455 | 499 |
456 int EchoCancellationImpl::num_handles_required() const { | 500 int EchoCancellationImpl::num_handles_required() const { |
501 // Only called from within APM, hence no locking is needed. | |
457 return apm_->num_output_channels() * | 502 return apm_->num_output_channels() * |
458 apm_->num_reverse_channels(); | 503 apm_->num_reverse_channels(); |
459 } | 504 } |
460 | 505 |
461 int EchoCancellationImpl::GetHandleError(void* handle) const { | 506 int EchoCancellationImpl::GetHandleError(void* handle) const { |
507 // Only called from within APM, hence no locking is needed. | |
462 assert(handle != NULL); | 508 assert(handle != NULL); |
463 return AudioProcessing::kUnspecifiedError; | 509 return AudioProcessing::kUnspecifiedError; |
464 } | 510 } |
465 | 511 |
466 } // namespace webrtc | 512 } // namespace webrtc |
OLD | NEW |