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 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 return AudioProcessing::kBadStreamParameterWarning; | 48 return AudioProcessing::kBadStreamParameterWarning; |
| 49 default: | 49 default: |
| 50 // AEC_UNSPECIFIED_ERROR | 50 // AEC_UNSPECIFIED_ERROR |
| 51 // AEC_UNINITIALIZED_ERROR | 51 // AEC_UNINITIALIZED_ERROR |
| 52 // AEC_NULL_POINTER_ERROR | 52 // AEC_NULL_POINTER_ERROR |
| 53 return AudioProcessing::kUnspecifiedError; | 53 return AudioProcessing::kUnspecifiedError; |
| 54 } | 54 } |
| 55 } | 55 } |
| 56 } // namespace | 56 } // namespace |
| 57 | 57 |
| 58 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame1; | |
| 59 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame2; | |
| 60 | |
| 58 EchoCancellationImpl::EchoCancellationImpl(const AudioProcessing* apm, | 61 EchoCancellationImpl::EchoCancellationImpl(const AudioProcessing* apm, |
| 59 CriticalSectionWrapper* crit) | 62 CriticalSectionWrapper* crit) |
| 60 : ProcessingComponent(), | 63 : ProcessingComponent(), |
| 61 apm_(apm), | 64 apm_(apm), |
| 62 crit_(crit), | 65 crit_(crit), |
| 63 drift_compensation_enabled_(false), | 66 drift_compensation_enabled_(false), |
| 64 metrics_enabled_(false), | 67 metrics_enabled_(false), |
| 65 suppression_level_(kModerateSuppression), | 68 suppression_level_(kModerateSuppression), |
| 66 stream_drift_samples_(0), | 69 stream_drift_samples_(0), |
| 67 was_stream_drift_set_(false), | 70 was_stream_drift_set_(false), |
| 68 stream_has_echo_(false), | 71 stream_has_echo_(false), |
| 69 delay_logging_enabled_(false), | 72 delay_logging_enabled_(false), |
| 70 extended_filter_enabled_(false), | 73 extended_filter_enabled_(false), |
| 71 delay_agnostic_enabled_(false) { | 74 delay_agnostic_enabled_(false), |
| 75 render_queue_element_max_size_(0) { | |
| 76 AllocateRenderQueue(); | |
| 72 } | 77 } |
| 73 | 78 |
| 74 EchoCancellationImpl::~EchoCancellationImpl() {} | 79 EchoCancellationImpl::~EchoCancellationImpl() {} |
| 75 | 80 |
| 76 int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) { | 81 int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) { |
| 77 if (!is_component_enabled()) { | 82 if (!is_component_enabled()) { |
| 78 return apm_->kNoError; | 83 return apm_->kNoError; |
| 79 } | 84 } |
| 80 | 85 |
| 81 assert(audio->num_frames_per_band() <= 160); | 86 assert(audio->num_frames_per_band() <= 160); |
| 82 assert(audio->num_channels() == apm_->num_reverse_channels()); | 87 assert(audio->num_channels() == apm_->num_reverse_channels()); |
| 83 | 88 |
| 84 int err = apm_->kNoError; | 89 int err = apm_->kNoError; |
| 85 | 90 |
| 86 // The ordering convention must be followed to pass to the correct AEC. | 91 // The ordering convention must be followed to pass to the correct AEC. |
| 87 size_t handle_index = 0; | 92 size_t handle_index = 0; |
| 93 int buffer_index = 0; | |
| 88 for (int i = 0; i < apm_->num_output_channels(); i++) { | 94 for (int i = 0; i < apm_->num_output_channels(); i++) { |
| 89 for (int j = 0; j < audio->num_channels(); j++) { | 95 for (int j = 0; j < audio->num_channels(); j++) { |
| 90 Handle* my_handle = static_cast<Handle*>(handle(handle_index)); | 96 Handle* my_handle = static_cast<Handle*>(handle(handle_index)); |
| 91 err = WebRtcAec_BufferFarend( | 97 // Retrieve any error code produced by the buffering of the farend |
| 92 my_handle, | 98 // signal |
| 93 audio->split_bands_const_f(j)[kBand0To8kHz], | 99 err = WebRtcAec_GetBufferFarendError( |
| 100 my_handle, audio->split_bands_const_f(j)[kBand0To8kHz], | |
| 94 audio->num_frames_per_band()); | 101 audio->num_frames_per_band()); |
| 95 | 102 |
| 96 if (err != apm_->kNoError) { | 103 if (err != apm_->kNoError) { |
| 97 return MapError(err); // TODO(ajm): warning possible? | 104 return MapError(err); // TODO(ajm): warning possible? |
| 98 } | 105 } |
| 99 | 106 |
| 107 // Buffer the samples in the render queue. | |
| 108 RTC_DCHECK((buffer_index + audio->num_frames_per_band()) <= | |
| 109 render_queue_element_max_size_); | |
| 110 | |
| 111 memcpy(&render_queue_buffer_[buffer_index], | |
| 112 audio->split_bands_const_f(j)[kBand0To8kHz], | |
| 113 (audio->num_frames_per_band() * | |
| 114 sizeof(*audio->split_bands_const_f(j)[kBand0To8kHz]))); | |
| 115 | |
| 116 buffer_index += audio->num_frames_per_band(); | |
|
kwiberg-webrtc
2015/10/27 10:43:07
Can't you use the nurmal features of std::vector t
peah-webrtc
2015/10/29 11:36:56
Done.
| |
| 117 | |
| 100 handle_index++; | 118 handle_index++; |
| 101 } | 119 } |
| 102 } | 120 } |
| 103 | 121 |
| 122 render_queue_buffer_.resize(buffer_index); | |
| 123 render_signal_queue_->Insert(&render_queue_buffer_); | |
|
kwiberg-webrtc
2015/10/27 10:43:07
Doesn't Insert return a status bool that you'd wan
peah-webrtc
2015/10/29 11:36:56
Done.
| |
| 124 | |
| 104 return apm_->kNoError; | 125 return apm_->kNoError; |
| 105 } | 126 } |
| 106 | 127 |
| 128 // Read chunks of data that were received and queued on the render side from | |
| 129 // a queue. All the data chunks are buffered into the farend signal of the AEC. | |
| 130 void EchoCancellationImpl::ReadQueuedRenderData() { | |
| 131 if (!is_component_enabled()) { | |
| 132 return; | |
| 133 } | |
| 134 | |
| 135 bool samples_read = render_signal_queue_->Remove(&capture_queue_buffer_); | |
| 136 while (samples_read) { | |
|
kwiberg-webrtc
2015/10/27 10:43:07
Just
while (render_signal_queue_->Remove(&captu
peah-webrtc
2015/10/29 11:36:56
Done.
| |
| 137 size_t handle_index = 0; | |
| 138 int buffer_index = 0; | |
| 139 const int num_frames_per_band = | |
| 140 capture_queue_buffer_.size() / | |
| 141 (apm_->num_output_channels() * apm_->num_reverse_channels()); | |
| 142 for (int i = 0; i < apm_->num_output_channels(); i++) { | |
| 143 for (int j = 0; j < apm_->num_reverse_channels(); j++) { | |
| 144 Handle* my_handle = static_cast<Handle*>(handle(handle_index)); | |
| 145 (void)WebRtcAec_BufferFarend(my_handle, | |
| 146 &capture_queue_buffer_[buffer_index], | |
| 147 num_frames_per_band); | |
| 148 | |
| 149 buffer_index += num_frames_per_band; | |
| 150 handle_index++; | |
| 151 } | |
| 152 } | |
| 153 samples_read = render_signal_queue_->Remove(&capture_queue_buffer_); | |
| 154 } | |
| 155 } | |
| 156 | |
| 107 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) { | 157 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) { |
| 108 if (!is_component_enabled()) { | 158 if (!is_component_enabled()) { |
| 109 return apm_->kNoError; | 159 return apm_->kNoError; |
| 110 } | 160 } |
| 111 | 161 |
| 112 if (!apm_->was_stream_delay_set()) { | 162 if (!apm_->was_stream_delay_set()) { |
| 113 return apm_->kStreamParameterNotSetError; | 163 return apm_->kStreamParameterNotSetError; |
| 114 } | 164 } |
| 115 | 165 |
| 116 if (drift_compensation_enabled_ && !was_stream_drift_set_) { | 166 if (drift_compensation_enabled_ && !was_stream_drift_set_) { |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 Handle* my_handle = static_cast<Handle*>(handle(0)); | 376 Handle* my_handle = static_cast<Handle*>(handle(0)); |
| 327 return WebRtcAec_aec_core(my_handle); | 377 return WebRtcAec_aec_core(my_handle); |
| 328 } | 378 } |
| 329 | 379 |
| 330 int EchoCancellationImpl::Initialize() { | 380 int EchoCancellationImpl::Initialize() { |
| 331 int err = ProcessingComponent::Initialize(); | 381 int err = ProcessingComponent::Initialize(); |
| 332 if (err != apm_->kNoError || !is_component_enabled()) { | 382 if (err != apm_->kNoError || !is_component_enabled()) { |
| 333 return err; | 383 return err; |
| 334 } | 384 } |
| 335 | 385 |
| 386 AllocateRenderQueue(); | |
| 387 | |
| 336 return apm_->kNoError; | 388 return apm_->kNoError; |
| 337 } | 389 } |
| 338 | 390 |
| 391 void EchoCancellationImpl::AllocateRenderQueue() { | |
| 392 const size_t max_frame_size = std::max(kAllowedValuesOfSamplesPerFrame1, | |
| 393 kAllowedValuesOfSamplesPerFrame2); | |
| 394 const size_t min_frame_size = std::min(kAllowedValuesOfSamplesPerFrame1, | |
| 395 kAllowedValuesOfSamplesPerFrame2); | |
| 396 | |
| 397 render_queue_element_max_size_ = | |
| 398 (max_frame_size * num_handles_required()); | |
|
kwiberg-webrtc
2015/10/27 10:43:07
Unnecessary parentheses.
peah-webrtc
2015/10/29 11:36:56
Done.
| |
| 399 | |
| 400 const size_t render_queue_element_min_size = | |
| 401 (min_frame_size * num_handles_required()); | |
|
kwiberg-webrtc
2015/10/27 10:43:07
Unnecessary parentheses.
peah-webrtc
2015/10/29 11:36:56
Done.
| |
| 402 | |
| 403 std::vector<float> template_queue_element(render_queue_element_max_size_); | |
| 404 | |
| 405 render_signal_queue_.reset( | |
| 406 new SwapQueue<std::vector<float>, AecRenderQueueItemVerifier>( | |
| 407 kMaxNumFramesToBuffer, | |
| 408 AecRenderQueueItemVerifier(render_queue_element_min_size, | |
| 409 render_queue_element_max_size_), | |
| 410 template_queue_element)); | |
| 411 | |
| 412 render_queue_buffer_.resize(render_queue_element_max_size_); | |
| 413 capture_queue_buffer_.resize(render_queue_element_max_size_); | |
| 414 } | |
| 415 | |
| 339 void EchoCancellationImpl::SetExtraOptions(const Config& config) { | 416 void EchoCancellationImpl::SetExtraOptions(const Config& config) { |
| 340 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; | 417 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; |
| 341 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; | 418 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; |
| 342 Configure(); | 419 Configure(); |
| 343 } | 420 } |
| 344 | 421 |
| 345 void* EchoCancellationImpl::CreateHandle() const { | 422 void* EchoCancellationImpl::CreateHandle() const { |
| 346 return WebRtcAec_Create(); | 423 return WebRtcAec_Create(); |
| 347 } | 424 } |
| 348 | 425 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 361 48000); | 438 48000); |
| 362 } | 439 } |
| 363 | 440 |
| 364 int EchoCancellationImpl::ConfigureHandle(void* handle) const { | 441 int EchoCancellationImpl::ConfigureHandle(void* handle) const { |
| 365 assert(handle != NULL); | 442 assert(handle != NULL); |
| 366 AecConfig config; | 443 AecConfig config; |
| 367 config.metricsMode = metrics_enabled_; | 444 config.metricsMode = metrics_enabled_; |
| 368 config.nlpMode = MapSetting(suppression_level_); | 445 config.nlpMode = MapSetting(suppression_level_); |
| 369 config.skewMode = drift_compensation_enabled_; | 446 config.skewMode = drift_compensation_enabled_; |
| 370 config.delay_logging = delay_logging_enabled_; | 447 config.delay_logging = delay_logging_enabled_; |
| 371 | |
| 372 WebRtcAec_enable_extended_filter( | 448 WebRtcAec_enable_extended_filter( |
| 373 WebRtcAec_aec_core(static_cast<Handle*>(handle)), | 449 WebRtcAec_aec_core(static_cast<Handle*>(handle)), |
| 374 extended_filter_enabled_ ? 1 : 0); | 450 extended_filter_enabled_ ? 1 : 0); |
| 375 WebRtcAec_enable_delay_agnostic( | 451 WebRtcAec_enable_delay_agnostic( |
| 376 WebRtcAec_aec_core(static_cast<Handle*>(handle)), | 452 WebRtcAec_aec_core(static_cast<Handle*>(handle)), |
| 377 delay_agnostic_enabled_ ? 1 : 0); | 453 delay_agnostic_enabled_ ? 1 : 0); |
| 378 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); | 454 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); |
| 379 } | 455 } |
| 380 | 456 |
| 381 int EchoCancellationImpl::num_handles_required() const { | 457 int EchoCancellationImpl::num_handles_required() const { |
| 382 return apm_->num_output_channels() * | 458 return apm_->num_output_channels() * |
| 383 apm_->num_reverse_channels(); | 459 apm_->num_reverse_channels(); |
| 384 } | 460 } |
| 385 | 461 |
| 386 int EchoCancellationImpl::GetHandleError(void* handle) const { | 462 int EchoCancellationImpl::GetHandleError(void* handle) const { |
| 387 assert(handle != NULL); | 463 assert(handle != NULL); |
| 388 return AudioProcessing::kUnspecifiedError; | 464 return AudioProcessing::kUnspecifiedError; |
| 389 } | 465 } |
| 466 | |
| 390 } // namespace webrtc | 467 } // namespace webrtc |
| OLD | NEW |