Chromium Code Reviews| 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/modules/audio_processing/aec/echo_cancellation.h" | 19 #include "webrtc/modules/audio_processing/aec/echo_cancellation.h" |
| 20 #include "webrtc/modules/audio_processing/audio_buffer.h" | 20 #include "webrtc/modules/audio_processing/audio_buffer.h" |
| 21 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
| 22 | 21 |
| 23 namespace webrtc { | 22 namespace webrtc { |
| 24 | 23 |
| 25 typedef void Handle; | 24 typedef void Handle; |
| 26 | 25 |
| 27 namespace { | 26 namespace { |
| 28 int16_t MapSetting(EchoCancellation::SuppressionLevel level) { | 27 int16_t MapSetting(EchoCancellation::SuppressionLevel level) { |
| 29 switch (level) { | 28 switch (level) { |
| 30 case EchoCancellation::kLowSuppression: | 29 case EchoCancellation::kLowSuppression: |
| 31 return kAecNlpConservative; | 30 return kAecNlpConservative; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 57 // Maximum length that a frame of samples can have. | 56 // Maximum length that a frame of samples can have. |
| 58 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160; | 57 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160; |
| 59 // Maximum number of frames to buffer in the render queue. | 58 // Maximum number of frames to buffer in the render queue. |
| 60 // TODO(peah): Decrease this once we properly handle hugely unbalanced | 59 // TODO(peah): Decrease this once we properly handle hugely unbalanced |
| 61 // reverse and forward call numbers. | 60 // reverse and forward call numbers. |
| 62 static const size_t kMaxNumFramesToBuffer = 100; | 61 static const size_t kMaxNumFramesToBuffer = 100; |
| 63 } // namespace | 62 } // namespace |
| 64 | 63 |
| 65 EchoCancellationImpl::EchoCancellationImpl( | 64 EchoCancellationImpl::EchoCancellationImpl( |
| 66 const AudioProcessing* apm, | 65 const AudioProcessing* apm, |
| 67 CriticalSectionWrapper* crit, | 66 rtc::CriticalSection* crit_render, |
| 67 rtc::CriticalSection* crit_capture, | |
| 68 const rtc::ThreadChecker* render_thread_checker) | 68 const rtc::ThreadChecker* render_thread_checker) |
| 69 : ProcessingComponent(), | 69 : ProcessingComponent(), |
| 70 apm_(apm), | 70 apm_(apm), |
| 71 crit_(crit), | 71 crit_render_(crit_render), |
| 72 crit_capture_(crit_capture), | |
| 72 render_thread_checker_(render_thread_checker), | 73 render_thread_checker_(render_thread_checker), |
| 73 drift_compensation_enabled_(false), | 74 drift_compensation_enabled_(false), |
| 74 metrics_enabled_(false), | 75 metrics_enabled_(false), |
| 75 suppression_level_(kModerateSuppression), | 76 suppression_level_(kModerateSuppression), |
| 76 stream_drift_samples_(0), | 77 stream_drift_samples_(0), |
| 77 was_stream_drift_set_(false), | 78 was_stream_drift_set_(false), |
| 78 stream_has_echo_(false), | 79 stream_has_echo_(false), |
| 79 delay_logging_enabled_(false), | 80 delay_logging_enabled_(false), |
| 80 extended_filter_enabled_(false), | 81 extended_filter_enabled_(false), |
| 81 delay_agnostic_enabled_(false), | 82 delay_agnostic_enabled_(false), |
| 82 render_queue_element_max_size_(0) {} | 83 render_queue_element_max_size_(0) {} |
|
the sun
2015/11/23 21:36:05
crit_render and crit_capture must be set; that's p
| |
| 83 | 84 |
| 84 EchoCancellationImpl::~EchoCancellationImpl() {} | 85 EchoCancellationImpl::~EchoCancellationImpl() {} |
| 85 | 86 |
| 86 int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) { | 87 int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) { |
| 87 RTC_DCHECK(render_thread_checker_->CalledOnValidThread()); | 88 RTC_DCHECK(render_thread_checker_->CalledOnValidThread()); |
| 88 if (!is_component_enabled()) { | 89 if (!is_component_enabled()) { |
| 89 return apm_->kNoError; | 90 return apm_->kNoError; |
| 90 } | 91 } |
| 91 | 92 |
| 92 assert(audio->num_frames_per_band() <= 160); | 93 assert(audio->num_frames_per_band() <= 160); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 113 // Buffer the samples in the render queue. | 114 // Buffer the samples in the render queue. |
| 114 render_queue_buffer_.insert(render_queue_buffer_.end(), | 115 render_queue_buffer_.insert(render_queue_buffer_.end(), |
| 115 audio->split_bands_const_f(j)[kBand0To8kHz], | 116 audio->split_bands_const_f(j)[kBand0To8kHz], |
| 116 (audio->split_bands_const_f(j)[kBand0To8kHz] + | 117 (audio->split_bands_const_f(j)[kBand0To8kHz] + |
| 117 audio->num_frames_per_band())); | 118 audio->num_frames_per_band())); |
| 118 } | 119 } |
| 119 } | 120 } |
| 120 | 121 |
| 121 // Insert the samples into the queue. | 122 // Insert the samples into the queue. |
| 122 if (!render_signal_queue_->Insert(&render_queue_buffer_)) { | 123 if (!render_signal_queue_->Insert(&render_queue_buffer_)) { |
| 123 ReadQueuedRenderData(); | 124 // The data queue is full and needs to be emptied. |
| 125 { | |
| 126 rtc::CritScope cs_capture(crit_capture_); | |
| 127 ReadQueuedRenderData(); | |
| 128 } | |
| 124 | 129 |
| 125 // Retry the insert (should always work). | 130 // Retry the insert (should always work). |
| 126 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); | 131 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); |
| 127 } | 132 } |
| 128 | 133 |
| 129 return apm_->kNoError; | 134 return apm_->kNoError; |
| 130 } | 135 } |
| 131 | 136 |
| 132 // 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 |
| 133 // 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. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 | 213 |
| 209 handle_index++; | 214 handle_index++; |
| 210 } | 215 } |
| 211 } | 216 } |
| 212 | 217 |
| 213 was_stream_drift_set_ = false; | 218 was_stream_drift_set_ = false; |
| 214 return apm_->kNoError; | 219 return apm_->kNoError; |
| 215 } | 220 } |
| 216 | 221 |
| 217 int EchoCancellationImpl::Enable(bool enable) { | 222 int EchoCancellationImpl::Enable(bool enable) { |
| 218 CriticalSectionScoped crit_scoped(crit_); | 223 // Run in a single-threaded manner. |
| 224 rtc::CritScope cs_render(crit_render_); | |
| 225 rtc::CritScope cs_capture(crit_capture_); | |
| 219 // Ensure AEC and AECM are not both enabled. | 226 // Ensure AEC and AECM are not both enabled. |
| 220 if (enable && apm_->echo_control_mobile()->is_enabled()) { | 227 if (enable && apm_->echo_control_mobile()->is_enabled()) { |
| 221 return apm_->kBadParameterError; | 228 return apm_->kBadParameterError; |
| 222 } | 229 } |
| 223 | 230 |
| 224 return EnableComponent(enable); | 231 return EnableComponent(enable); |
| 225 } | 232 } |
| 226 | 233 |
| 227 bool EchoCancellationImpl::is_enabled() const { | 234 bool EchoCancellationImpl::is_enabled() const { |
| 235 rtc::CritScope cs(crit_capture_); | |
| 228 return is_component_enabled(); | 236 return is_component_enabled(); |
| 229 } | 237 } |
| 230 | 238 |
| 231 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) { | 239 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) { |
| 232 CriticalSectionScoped crit_scoped(crit_); | 240 rtc::CritScope cs(crit_capture_); |
| 233 if (MapSetting(level) == -1) { | 241 if (MapSetting(level) == -1) { |
| 234 return apm_->kBadParameterError; | 242 return apm_->kBadParameterError; |
| 235 } | 243 } |
| 236 | 244 |
| 237 suppression_level_ = level; | 245 suppression_level_ = level; |
| 238 return Configure(); | 246 return Configure(); |
| 239 } | 247 } |
| 240 | 248 |
| 241 EchoCancellation::SuppressionLevel EchoCancellationImpl::suppression_level() | 249 EchoCancellation::SuppressionLevel EchoCancellationImpl::suppression_level() |
| 242 const { | 250 const { |
| 251 rtc::CritScope cs(crit_capture_); | |
| 243 return suppression_level_; | 252 return suppression_level_; |
| 244 } | 253 } |
| 245 | 254 |
| 246 int EchoCancellationImpl::enable_drift_compensation(bool enable) { | 255 int EchoCancellationImpl::enable_drift_compensation(bool enable) { |
| 247 CriticalSectionScoped crit_scoped(crit_); | 256 rtc::CritScope cs(crit_capture_); |
|
the sun
2015/11/23 21:36:05
It's great that you have added these. Thank you!
peah-webrtc
2015/11/24 21:42:23
You are welcome! :-)
Acknowledged.
| |
| 248 drift_compensation_enabled_ = enable; | 257 drift_compensation_enabled_ = enable; |
| 249 return Configure(); | 258 return Configure(); |
| 250 } | 259 } |
| 251 | 260 |
| 252 bool EchoCancellationImpl::is_drift_compensation_enabled() const { | 261 bool EchoCancellationImpl::is_drift_compensation_enabled() const { |
| 262 rtc::CritScope cs(crit_capture_); | |
| 253 return drift_compensation_enabled_; | 263 return drift_compensation_enabled_; |
| 254 } | 264 } |
| 255 | 265 |
| 256 void EchoCancellationImpl::set_stream_drift_samples(int drift) { | 266 void EchoCancellationImpl::set_stream_drift_samples(int drift) { |
| 267 rtc::CritScope cs(crit_capture_); | |
| 257 was_stream_drift_set_ = true; | 268 was_stream_drift_set_ = true; |
| 258 stream_drift_samples_ = drift; | 269 stream_drift_samples_ = drift; |
| 259 } | 270 } |
| 260 | 271 |
| 261 int EchoCancellationImpl::stream_drift_samples() const { | 272 int EchoCancellationImpl::stream_drift_samples() const { |
| 273 rtc::CritScope cs(crit_capture_); | |
| 262 return stream_drift_samples_; | 274 return stream_drift_samples_; |
| 263 } | 275 } |
| 264 | 276 |
| 265 int EchoCancellationImpl::enable_metrics(bool enable) { | 277 int EchoCancellationImpl::enable_metrics(bool enable) { |
| 266 CriticalSectionScoped crit_scoped(crit_); | 278 rtc::CritScope cs(crit_capture_); |
| 267 metrics_enabled_ = enable; | 279 metrics_enabled_ = enable; |
| 268 return Configure(); | 280 return Configure(); |
| 269 } | 281 } |
| 270 | 282 |
| 271 bool EchoCancellationImpl::are_metrics_enabled() const { | 283 bool EchoCancellationImpl::are_metrics_enabled() const { |
| 284 rtc::CritScope cs(crit_capture_); | |
| 272 return metrics_enabled_; | 285 return metrics_enabled_; |
| 273 } | 286 } |
| 274 | 287 |
| 275 // TODO(ajm): we currently just use the metrics from the first AEC. Think more | 288 // TODO(ajm): we currently just use the metrics from the first AEC. Think more |
| 276 // aboue the best way to extend this to multi-channel. | 289 // aboue the best way to extend this to multi-channel. |
| 277 int EchoCancellationImpl::GetMetrics(Metrics* metrics) { | 290 int EchoCancellationImpl::GetMetrics(Metrics* metrics) { |
| 278 CriticalSectionScoped crit_scoped(crit_); | 291 rtc::CritScope cs(crit_capture_); |
| 279 if (metrics == NULL) { | 292 if (metrics == NULL) { |
| 280 return apm_->kNullPointerError; | 293 return apm_->kNullPointerError; |
| 281 } | 294 } |
| 282 | 295 |
| 283 if (!is_component_enabled() || !metrics_enabled_) { | 296 if (!is_component_enabled() || !metrics_enabled_) { |
| 284 return apm_->kNotEnabledError; | 297 return apm_->kNotEnabledError; |
| 285 } | 298 } |
| 286 | 299 |
| 287 AecMetrics my_metrics; | 300 AecMetrics my_metrics; |
| 288 memset(&my_metrics, 0, sizeof(my_metrics)); | 301 memset(&my_metrics, 0, sizeof(my_metrics)); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 311 | 324 |
| 312 metrics->a_nlp.instant = my_metrics.aNlp.instant; | 325 metrics->a_nlp.instant = my_metrics.aNlp.instant; |
| 313 metrics->a_nlp.average = my_metrics.aNlp.average; | 326 metrics->a_nlp.average = my_metrics.aNlp.average; |
| 314 metrics->a_nlp.maximum = my_metrics.aNlp.max; | 327 metrics->a_nlp.maximum = my_metrics.aNlp.max; |
| 315 metrics->a_nlp.minimum = my_metrics.aNlp.min; | 328 metrics->a_nlp.minimum = my_metrics.aNlp.min; |
| 316 | 329 |
| 317 return apm_->kNoError; | 330 return apm_->kNoError; |
| 318 } | 331 } |
| 319 | 332 |
| 320 bool EchoCancellationImpl::stream_has_echo() const { | 333 bool EchoCancellationImpl::stream_has_echo() const { |
| 334 // This is called both from within and from outside of APM, with and | |
| 335 // without locks set. Hence the conditional lock handling below. | |
| 336 rtc::TryCritScope cs(crit_capture_); | |
|
the sun
2015/11/23 21:36:05
I don't understand why you are using TryCritScope
peah-webrtc
2015/11/24 21:42:23
Agree, something is wrong with this. I'll revise.
| |
| 337 | |
| 338 // Call the lock function (without this call TryCritScope will DCHECK). | |
|
the sun
2015/11/23 21:36:05
TryCritScope::locked() does *not* call any lock fu
peah-webrtc
2015/11/24 21:42:23
Of course you are correct, I'll revise. Please re-
| |
| 339 (void)cs.locked(); | |
| 340 | |
|
kwiberg-webrtc
2015/11/23 22:15:11
This doesn't look right. The effect here is to tak
peah-webrtc
2015/11/24 21:42:23
I agree on both, it was not correct, but I revised
| |
| 321 return stream_has_echo_; | 341 return stream_has_echo_; |
| 322 } | 342 } |
| 323 | 343 |
| 324 int EchoCancellationImpl::enable_delay_logging(bool enable) { | 344 int EchoCancellationImpl::enable_delay_logging(bool enable) { |
| 325 CriticalSectionScoped crit_scoped(crit_); | 345 // This is called both from within and from outside of APM, with and |
| 346 // without locks set. Hence the conditional lock handling below. | |
| 347 rtc::TryCritScope cs(crit_capture_); | |
| 348 | |
| 349 // Call the lock function (without this call TryCritScope will DCHECK). | |
| 350 (void)cs.locked(); | |
| 351 | |
|
kwiberg-webrtc
2015/11/23 22:15:11
Same.
peah-webrtc
2015/11/24 21:42:24
Agree, please look at the revised solution.
| |
| 326 delay_logging_enabled_ = enable; | 352 delay_logging_enabled_ = enable; |
| 327 return Configure(); | 353 return Configure(); |
|
the sun
2015/11/23 21:36:05
You may be setting delay_logging_enabled_ and call
peah-webrtc
2015/11/24 21:42:24
Agree, that was a bad design, but the revised code
| |
| 328 } | 354 } |
| 329 | 355 |
| 330 bool EchoCancellationImpl::is_delay_logging_enabled() const { | 356 bool EchoCancellationImpl::is_delay_logging_enabled() const { |
| 357 rtc::CritScope cs(crit_capture_); | |
| 331 return delay_logging_enabled_; | 358 return delay_logging_enabled_; |
| 332 } | 359 } |
| 333 | 360 |
| 334 bool EchoCancellationImpl::is_delay_agnostic_enabled() const { | 361 bool EchoCancellationImpl::is_delay_agnostic_enabled() const { |
| 362 // Only called from within APM, hence no locking is needed. | |
| 335 return delay_agnostic_enabled_; | 363 return delay_agnostic_enabled_; |
| 336 } | 364 } |
| 337 | 365 |
| 338 bool EchoCancellationImpl::is_extended_filter_enabled() const { | 366 bool EchoCancellationImpl::is_extended_filter_enabled() const { |
| 367 // Only called from within APM, hence no locking is needed. | |
| 339 return extended_filter_enabled_; | 368 return extended_filter_enabled_; |
| 340 } | 369 } |
| 341 | 370 |
| 342 // TODO(bjornv): How should we handle the multi-channel case? | 371 // TODO(bjornv): How should we handle the multi-channel case? |
| 343 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std) { | 372 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std) { |
| 373 rtc::CritScope cs(crit_capture_); | |
| 344 float fraction_poor_delays = 0; | 374 float fraction_poor_delays = 0; |
| 345 return GetDelayMetrics(median, std, &fraction_poor_delays); | 375 return GetDelayMetrics(median, std, &fraction_poor_delays); |
| 346 } | 376 } |
| 347 | 377 |
| 348 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std, | 378 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std, |
| 349 float* fraction_poor_delays) { | 379 float* fraction_poor_delays) { |
| 350 CriticalSectionScoped crit_scoped(crit_); | 380 rtc::CritScope cs(crit_capture_); |
| 351 if (median == NULL) { | 381 if (median == NULL) { |
| 352 return apm_->kNullPointerError; | 382 return apm_->kNullPointerError; |
| 353 } | 383 } |
| 354 if (std == NULL) { | 384 if (std == NULL) { |
| 355 return apm_->kNullPointerError; | 385 return apm_->kNullPointerError; |
| 356 } | 386 } |
| 357 | 387 |
| 358 if (!is_component_enabled() || !delay_logging_enabled_) { | 388 if (!is_component_enabled() || !delay_logging_enabled_) { |
| 359 return apm_->kNotEnabledError; | 389 return apm_->kNotEnabledError; |
| 360 } | 390 } |
| 361 | 391 |
| 362 Handle* my_handle = static_cast<Handle*>(handle(0)); | 392 Handle* my_handle = static_cast<Handle*>(handle(0)); |
| 363 const int err = | 393 const int err = |
| 364 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays); | 394 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays); |
| 365 if (err != apm_->kNoError) { | 395 if (err != apm_->kNoError) { |
| 366 return MapError(err); | 396 return MapError(err); |
| 367 } | 397 } |
| 368 | 398 |
| 369 return apm_->kNoError; | 399 return apm_->kNoError; |
| 370 } | 400 } |
| 371 | 401 |
| 372 struct AecCore* EchoCancellationImpl::aec_core() const { | 402 struct AecCore* EchoCancellationImpl::aec_core() const { |
| 373 CriticalSectionScoped crit_scoped(crit_); | 403 // Only called from within APM, hence no locking is needed. |
| 374 if (!is_component_enabled()) { | 404 if (!is_component_enabled()) { |
| 375 return NULL; | 405 return NULL; |
| 376 } | 406 } |
| 377 Handle* my_handle = static_cast<Handle*>(handle(0)); | 407 Handle* my_handle = static_cast<Handle*>(handle(0)); |
| 378 return WebRtcAec_aec_core(my_handle); | 408 return WebRtcAec_aec_core(my_handle); |
| 379 } | 409 } |
| 380 | 410 |
| 381 int EchoCancellationImpl::Initialize() { | 411 int EchoCancellationImpl::Initialize() { |
| 412 // Only called from within APM, hence no locking is needed. | |
|
the sun
2015/11/23 21:36:05
What do you mean with "called from within APM"? Al
peah-webrtc
2015/11/24 21:42:24
No, it is actually not, although I think I see you
| |
| 382 int err = ProcessingComponent::Initialize(); | 413 int err = ProcessingComponent::Initialize(); |
| 383 if (err != apm_->kNoError || !is_component_enabled()) { | 414 if (err != apm_->kNoError || !is_component_enabled()) { |
| 384 return err; | 415 return err; |
| 385 } | 416 } |
| 386 | 417 |
| 387 AllocateRenderQueue(); | 418 AllocateRenderQueue(); |
| 388 | 419 |
| 389 return apm_->kNoError; | 420 return apm_->kNoError; |
| 390 } | 421 } |
| 391 | 422 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 407 RenderQueueItemVerifier<float>(render_queue_element_max_size_))); | 438 RenderQueueItemVerifier<float>(render_queue_element_max_size_))); |
| 408 | 439 |
| 409 render_queue_buffer_.resize(render_queue_element_max_size_); | 440 render_queue_buffer_.resize(render_queue_element_max_size_); |
| 410 capture_queue_buffer_.resize(render_queue_element_max_size_); | 441 capture_queue_buffer_.resize(render_queue_element_max_size_); |
| 411 } else { | 442 } else { |
| 412 render_signal_queue_->Clear(); | 443 render_signal_queue_->Clear(); |
| 413 } | 444 } |
| 414 } | 445 } |
| 415 | 446 |
| 416 void EchoCancellationImpl::SetExtraOptions(const Config& config) { | 447 void EchoCancellationImpl::SetExtraOptions(const Config& config) { |
| 448 // This is called both from within and from outside of APM, with and | |
| 449 // without locks set. Hence the conditional lock handling below. | |
| 450 rtc::TryCritScope cs(crit_capture_); | |
| 451 | |
| 452 // Call the lock function (without this call TryCritScope will DCHECK). | |
| 453 (void)cs.locked(); | |
| 454 | |
|
kwiberg-webrtc
2015/11/23 22:15:11
Same.
peah-webrtc
2015/11/24 21:42:23
Agree. Please see the revised version.
| |
| 417 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; | 455 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; |
| 418 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; | 456 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; |
| 419 Configure(); | 457 Configure(); |
| 420 } | 458 } |
| 421 | 459 |
| 422 void* EchoCancellationImpl::CreateHandle() const { | 460 void* EchoCancellationImpl::CreateHandle() const { |
| 461 // Only called from within APM, hence no locking is needed. | |
| 423 return WebRtcAec_Create(); | 462 return WebRtcAec_Create(); |
| 424 } | 463 } |
| 425 | 464 |
| 426 void EchoCancellationImpl::DestroyHandle(void* handle) const { | 465 void EchoCancellationImpl::DestroyHandle(void* handle) const { |
| 466 // Only called from within APM, hence no locking is needed. | |
| 427 assert(handle != NULL); | 467 assert(handle != NULL); |
| 428 WebRtcAec_Free(static_cast<Handle*>(handle)); | 468 WebRtcAec_Free(static_cast<Handle*>(handle)); |
| 429 } | 469 } |
| 430 | 470 |
| 431 int EchoCancellationImpl::InitializeHandle(void* handle) const { | 471 int EchoCancellationImpl::InitializeHandle(void* handle) const { |
| 472 // Only called from within APM, hence no locking is needed. | |
| 432 assert(handle != NULL); | 473 assert(handle != NULL); |
| 433 // TODO(ajm): Drift compensation is disabled in practice. If restored, it | 474 // TODO(ajm): Drift compensation is disabled in practice. If restored, it |
| 434 // 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. |
| 435 // For now, just hardcode a 48 kHz value. | 476 // For now, just hardcode a 48 kHz value. |
| 436 return WebRtcAec_Init(static_cast<Handle*>(handle), | 477 return WebRtcAec_Init(static_cast<Handle*>(handle), |
| 437 apm_->proc_sample_rate_hz(), | 478 apm_->proc_sample_rate_hz(), |
| 438 48000); | 479 48000); |
| 439 } | 480 } |
| 440 | 481 |
| 441 int EchoCancellationImpl::ConfigureHandle(void* handle) const { | 482 int EchoCancellationImpl::ConfigureHandle(void* handle) const { |
| 483 // Only called from within APM, hence no locking is needed. | |
|
the sun
2015/11/23 21:36:05
This function is called from ProcessingComponent::
peah-webrtc
2015/11/24 21:42:23
You are right in that the lock was not properly ac
| |
| 442 assert(handle != NULL); | 484 assert(handle != NULL); |
| 443 AecConfig config; | 485 AecConfig config; |
| 444 config.metricsMode = metrics_enabled_; | 486 config.metricsMode = metrics_enabled_; |
| 445 config.nlpMode = MapSetting(suppression_level_); | 487 config.nlpMode = MapSetting(suppression_level_); |
| 446 config.skewMode = drift_compensation_enabled_; | 488 config.skewMode = drift_compensation_enabled_; |
| 447 config.delay_logging = delay_logging_enabled_; | 489 config.delay_logging = delay_logging_enabled_; |
| 448 WebRtcAec_enable_extended_filter( | 490 WebRtcAec_enable_extended_filter( |
| 449 WebRtcAec_aec_core(static_cast<Handle*>(handle)), | 491 WebRtcAec_aec_core(static_cast<Handle*>(handle)), |
| 450 extended_filter_enabled_ ? 1 : 0); | 492 extended_filter_enabled_ ? 1 : 0); |
| 451 WebRtcAec_enable_delay_agnostic( | 493 WebRtcAec_enable_delay_agnostic( |
| 452 WebRtcAec_aec_core(static_cast<Handle*>(handle)), | 494 WebRtcAec_aec_core(static_cast<Handle*>(handle)), |
| 453 delay_agnostic_enabled_ ? 1 : 0); | 495 delay_agnostic_enabled_ ? 1 : 0); |
| 454 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); | 496 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); |
| 455 } | 497 } |
| 456 | 498 |
| 457 int EchoCancellationImpl::num_handles_required() const { | 499 int EchoCancellationImpl::num_handles_required() const { |
| 500 // Only called from within APM, hence no locking is needed. | |
| 458 return apm_->num_output_channels() * | 501 return apm_->num_output_channels() * |
| 459 apm_->num_reverse_channels(); | 502 apm_->num_reverse_channels(); |
| 460 } | 503 } |
| 461 | 504 |
| 462 int EchoCancellationImpl::GetHandleError(void* handle) const { | 505 int EchoCancellationImpl::GetHandleError(void* handle) const { |
| 506 // Only called from within APM, hence no locking is needed. | |
| 463 assert(handle != NULL); | 507 assert(handle != NULL); |
| 464 return AudioProcessing::kUnspecifiedError; | 508 return AudioProcessing::kUnspecifiedError; |
| 465 } | 509 } |
| 466 } // namespace webrtc | 510 } // namespace webrtc |
| OLD | NEW |