| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 case AEC_BAD_PARAMETER_WARNING: | 42 case AEC_BAD_PARAMETER_WARNING: |
| 43 return AudioProcessing::kBadStreamParameterWarning; | 43 return AudioProcessing::kBadStreamParameterWarning; |
| 44 default: | 44 default: |
| 45 // AEC_UNSPECIFIED_ERROR | 45 // AEC_UNSPECIFIED_ERROR |
| 46 // AEC_UNINITIALIZED_ERROR | 46 // AEC_UNINITIALIZED_ERROR |
| 47 // AEC_NULL_POINTER_ERROR | 47 // AEC_NULL_POINTER_ERROR |
| 48 return AudioProcessing::kUnspecifiedError; | 48 return AudioProcessing::kUnspecifiedError; |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 | 51 |
| 52 // Maximum length that a frame of samples can have. | |
| 53 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160; | |
| 54 // Maximum number of frames to buffer in the render queue. | |
| 55 // TODO(peah): Decrease this once we properly handle hugely unbalanced | |
| 56 // reverse and forward call numbers. | |
| 57 static const size_t kMaxNumFramesToBuffer = 100; | |
| 58 } // namespace | 52 } // namespace |
| 59 | 53 |
| 60 struct EchoCancellationImpl::StreamProperties { | 54 struct EchoCancellationImpl::StreamProperties { |
| 61 StreamProperties() = delete; | 55 StreamProperties() = delete; |
| 62 StreamProperties(int sample_rate_hz, | 56 StreamProperties(int sample_rate_hz, |
| 63 size_t num_reverse_channels, | 57 size_t num_reverse_channels, |
| 64 size_t num_output_channels, | 58 size_t num_output_channels, |
| 65 size_t num_proc_channels) | 59 size_t num_proc_channels) |
| 66 : sample_rate_hz(sample_rate_hz), | 60 : sample_rate_hz(sample_rate_hz), |
| 67 num_reverse_channels(num_reverse_channels), | 61 num_reverse_channels(num_reverse_channels), |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 crit_capture_(crit_capture), | 100 crit_capture_(crit_capture), |
| 107 drift_compensation_enabled_(false), | 101 drift_compensation_enabled_(false), |
| 108 metrics_enabled_(false), | 102 metrics_enabled_(false), |
| 109 suppression_level_(kModerateSuppression), | 103 suppression_level_(kModerateSuppression), |
| 110 stream_drift_samples_(0), | 104 stream_drift_samples_(0), |
| 111 was_stream_drift_set_(false), | 105 was_stream_drift_set_(false), |
| 112 stream_has_echo_(false), | 106 stream_has_echo_(false), |
| 113 delay_logging_enabled_(false), | 107 delay_logging_enabled_(false), |
| 114 extended_filter_enabled_(false), | 108 extended_filter_enabled_(false), |
| 115 delay_agnostic_enabled_(false), | 109 delay_agnostic_enabled_(false), |
| 116 aec3_enabled_(false), | 110 aec3_enabled_(false) { |
| 117 render_queue_element_max_size_(0) { | |
| 118 RTC_DCHECK(crit_render); | 111 RTC_DCHECK(crit_render); |
| 119 RTC_DCHECK(crit_capture); | 112 RTC_DCHECK(crit_capture); |
| 120 } | 113 } |
| 121 | 114 |
| 122 EchoCancellationImpl::~EchoCancellationImpl() {} | 115 EchoCancellationImpl::~EchoCancellationImpl() = default; |
| 123 | 116 |
| 124 int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) { | 117 void EchoCancellationImpl::ProcessRenderAudio( |
| 125 rtc::CritScope cs_render(crit_render_); | 118 rtc::ArrayView<const float> packed_render_audio) { |
| 126 if (!enabled_) { | |
| 127 return AudioProcessing::kNoError; | |
| 128 } | |
| 129 | |
| 130 RTC_DCHECK(stream_properties_); | |
| 131 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); | |
| 132 RTC_DCHECK_EQ(audio->num_channels(), | |
| 133 stream_properties_->num_reverse_channels); | |
| 134 RTC_DCHECK_GE(cancellers_.size(), stream_properties_->num_output_channels * | |
| 135 audio->num_channels()); | |
| 136 | |
| 137 int err = AudioProcessing::kNoError; | |
| 138 | |
| 139 // The ordering convention must be followed to pass to the correct AEC. | |
| 140 size_t handle_index = 0; | |
| 141 render_queue_buffer_.clear(); | |
| 142 for (size_t i = 0; i < stream_properties_->num_output_channels; i++) { | |
| 143 for (size_t j = 0; j < audio->num_channels(); j++) { | |
| 144 // Retrieve any error code produced by the buffering of the farend | |
| 145 // signal. | |
| 146 err = WebRtcAec_GetBufferFarendError( | |
| 147 cancellers_[handle_index++]->state(), | |
| 148 audio->split_bands_const_f(j)[kBand0To8kHz], | |
| 149 audio->num_frames_per_band()); | |
| 150 | |
| 151 if (err != AudioProcessing::kNoError) { | |
| 152 return MapError(err); // TODO(ajm): warning possible? | |
| 153 } | |
| 154 | |
| 155 // Buffer the samples in the render queue. | |
| 156 render_queue_buffer_.insert(render_queue_buffer_.end(), | |
| 157 audio->split_bands_const_f(j)[kBand0To8kHz], | |
| 158 (audio->split_bands_const_f(j)[kBand0To8kHz] + | |
| 159 audio->num_frames_per_band())); | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 // Insert the samples into the queue. | |
| 164 if (!render_signal_queue_->Insert(&render_queue_buffer_)) { | |
| 165 // The data queue is full and needs to be emptied. | |
| 166 ReadQueuedRenderData(); | |
| 167 | |
| 168 // Retry the insert (should always work). | |
| 169 bool result = render_signal_queue_->Insert(&render_queue_buffer_); | |
| 170 RTC_DCHECK(result); | |
| 171 } | |
| 172 | |
| 173 return AudioProcessing::kNoError; | |
| 174 } | |
| 175 | |
| 176 // Read chunks of data that were received and queued on the render side from | |
| 177 // a queue. All the data chunks are buffered into the farend signal of the AEC. | |
| 178 void EchoCancellationImpl::ReadQueuedRenderData() { | |
| 179 rtc::CritScope cs_capture(crit_capture_); | 119 rtc::CritScope cs_capture(crit_capture_); |
| 180 if (!enabled_) { | 120 if (!enabled_) { |
| 181 return; | 121 return; |
| 182 } | 122 } |
| 183 | 123 |
| 184 RTC_DCHECK(stream_properties_); | 124 RTC_DCHECK(stream_properties_); |
| 185 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { | 125 size_t handle_index = 0; |
| 186 size_t handle_index = 0; | 126 size_t buffer_index = 0; |
| 187 size_t buffer_index = 0; | 127 const size_t num_frames_per_band = |
| 188 const size_t num_frames_per_band = | 128 packed_render_audio.size() / (stream_properties_->num_output_channels * |
| 189 capture_queue_buffer_.size() / | 129 stream_properties_->num_reverse_channels); |
| 190 (stream_properties_->num_output_channels * | 130 for (size_t i = 0; i < stream_properties_->num_output_channels; i++) { |
| 191 stream_properties_->num_reverse_channels); | 131 for (size_t j = 0; j < stream_properties_->num_reverse_channels; j++) { |
| 192 for (size_t i = 0; i < stream_properties_->num_output_channels; i++) { | 132 WebRtcAec_BufferFarend(cancellers_[handle_index++]->state(), |
| 193 for (size_t j = 0; j < stream_properties_->num_reverse_channels; j++) { | 133 &packed_render_audio[buffer_index], |
| 194 WebRtcAec_BufferFarend(cancellers_[handle_index++]->state(), | 134 num_frames_per_band); |
| 195 &capture_queue_buffer_[buffer_index], | |
| 196 num_frames_per_band); | |
| 197 | 135 |
| 198 buffer_index += num_frames_per_band; | 136 buffer_index += num_frames_per_band; |
| 199 } | |
| 200 } | 137 } |
| 201 } | 138 } |
| 202 } | 139 } |
| 203 | 140 |
| 141 |
| 204 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio, | 142 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio, |
| 205 int stream_delay_ms) { | 143 int stream_delay_ms) { |
| 206 rtc::CritScope cs_capture(crit_capture_); | 144 rtc::CritScope cs_capture(crit_capture_); |
| 207 if (!enabled_) { | 145 if (!enabled_) { |
| 208 return AudioProcessing::kNoError; | 146 return AudioProcessing::kNoError; |
| 209 } | 147 } |
| 210 | 148 |
| 211 if (drift_compensation_enabled_ && !was_stream_drift_set_) { | 149 if (drift_compensation_enabled_ && !was_stream_drift_set_) { |
| 212 return AudioProcessing::kStreamParameterNotSetError; | 150 return AudioProcessing::kStreamParameterNotSetError; |
| 213 } | 151 } |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 rtc::CritScope cs_capture(crit_capture_); | 411 rtc::CritScope cs_capture(crit_capture_); |
| 474 | 412 |
| 475 stream_properties_.reset( | 413 stream_properties_.reset( |
| 476 new StreamProperties(sample_rate_hz, num_reverse_channels, | 414 new StreamProperties(sample_rate_hz, num_reverse_channels, |
| 477 num_output_channels, num_proc_channels)); | 415 num_output_channels, num_proc_channels)); |
| 478 | 416 |
| 479 if (!enabled_) { | 417 if (!enabled_) { |
| 480 return; | 418 return; |
| 481 } | 419 } |
| 482 | 420 |
| 483 if (NumCancellersRequired() > cancellers_.size()) { | 421 const size_t num_cancellers_required = |
| 422 NumCancellersRequired(stream_properties_->num_output_channels, |
| 423 stream_properties_->num_reverse_channels); |
| 424 if (num_cancellers_required > cancellers_.size()) { |
| 484 const size_t cancellers_old_size = cancellers_.size(); | 425 const size_t cancellers_old_size = cancellers_.size(); |
| 485 cancellers_.resize(NumCancellersRequired()); | 426 cancellers_.resize(num_cancellers_required); |
| 486 | 427 |
| 487 for (size_t i = cancellers_old_size; i < cancellers_.size(); ++i) { | 428 for (size_t i = cancellers_old_size; i < cancellers_.size(); ++i) { |
| 488 cancellers_[i].reset(new Canceller()); | 429 cancellers_[i].reset(new Canceller()); |
| 489 } | 430 } |
| 490 } | 431 } |
| 491 | 432 |
| 492 for (auto& canceller : cancellers_) { | 433 for (auto& canceller : cancellers_) { |
| 493 canceller->Initialize(sample_rate_hz); | 434 canceller->Initialize(sample_rate_hz); |
| 494 } | 435 } |
| 495 | 436 |
| 496 Configure(); | 437 Configure(); |
| 497 | |
| 498 AllocateRenderQueue(); | |
| 499 } | 438 } |
| 500 | 439 |
| 501 int EchoCancellationImpl::GetSystemDelayInSamples() const { | 440 int EchoCancellationImpl::GetSystemDelayInSamples() const { |
| 502 rtc::CritScope cs(crit_capture_); | 441 rtc::CritScope cs(crit_capture_); |
| 503 RTC_DCHECK(enabled_); | 442 RTC_DCHECK(enabled_); |
| 504 // Report the delay for the first AEC component. | 443 // Report the delay for the first AEC component. |
| 505 return WebRtcAec_system_delay( | 444 return WebRtcAec_system_delay( |
| 506 WebRtcAec_aec_core(cancellers_[0]->state())); | 445 WebRtcAec_aec_core(cancellers_[0]->state())); |
| 507 } | 446 } |
| 508 | 447 |
| 509 void EchoCancellationImpl::AllocateRenderQueue() { | 448 void EchoCancellationImpl::PackRenderAudioBuffer( |
| 510 const size_t new_render_queue_element_max_size = std::max<size_t>( | 449 const AudioBuffer* audio, |
| 511 static_cast<size_t>(1), | 450 size_t num_output_channels, |
| 512 kMaxAllowedValuesOfSamplesPerFrame * NumCancellersRequired()); | 451 size_t num_channels, |
| 452 std::vector<float>* packed_buffer) { |
| 453 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); |
| 454 RTC_DCHECK_EQ(num_channels, audio->num_channels()); |
| 513 | 455 |
| 514 rtc::CritScope cs_render(crit_render_); | 456 packed_buffer->clear(); |
| 515 rtc::CritScope cs_capture(crit_capture_); | 457 // The ordering convention must be followed to pass the correct data. |
| 516 | 458 for (size_t i = 0; i < num_output_channels; i++) { |
| 517 // Reallocate the queue if the queue item size is too small to fit the | 459 for (size_t j = 0; j < audio->num_channels(); j++) { |
| 518 // data to put in the queue. | 460 // Buffer the samples in the render queue. |
| 519 if (render_queue_element_max_size_ < new_render_queue_element_max_size) { | 461 packed_buffer->insert(packed_buffer->end(), |
| 520 render_queue_element_max_size_ = new_render_queue_element_max_size; | 462 audio->split_bands_const_f(j)[kBand0To8kHz], |
| 521 | 463 (audio->split_bands_const_f(j)[kBand0To8kHz] + |
| 522 std::vector<float> template_queue_element(render_queue_element_max_size_); | 464 audio->num_frames_per_band())); |
| 523 | 465 } |
| 524 render_signal_queue_.reset( | |
| 525 new SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>( | |
| 526 kMaxNumFramesToBuffer, template_queue_element, | |
| 527 RenderQueueItemVerifier<float>(render_queue_element_max_size_))); | |
| 528 | |
| 529 render_queue_buffer_.resize(render_queue_element_max_size_); | |
| 530 capture_queue_buffer_.resize(render_queue_element_max_size_); | |
| 531 } else { | |
| 532 render_signal_queue_->Clear(); | |
| 533 } | 466 } |
| 534 } | 467 } |
| 535 | 468 |
| 536 void EchoCancellationImpl::SetExtraOptions(const webrtc::Config& config) { | 469 void EchoCancellationImpl::SetExtraOptions(const webrtc::Config& config) { |
| 537 { | 470 { |
| 538 rtc::CritScope cs(crit_capture_); | 471 rtc::CritScope cs(crit_capture_); |
| 539 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; | 472 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; |
| 540 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; | 473 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; |
| 541 refined_adaptive_filter_enabled_ = | 474 refined_adaptive_filter_enabled_ = |
| 542 config.Get<RefinedAdaptiveFilter>().enabled; | 475 config.Get<RefinedAdaptiveFilter>().enabled; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 566 WebRtcAec_aec_core(canceller->state()), | 499 WebRtcAec_aec_core(canceller->state()), |
| 567 refined_adaptive_filter_enabled_); | 500 refined_adaptive_filter_enabled_); |
| 568 const int handle_error = WebRtcAec_set_config(canceller->state(), config); | 501 const int handle_error = WebRtcAec_set_config(canceller->state(), config); |
| 569 if (handle_error != AudioProcessing::kNoError) { | 502 if (handle_error != AudioProcessing::kNoError) { |
| 570 error = AudioProcessing::kNoError; | 503 error = AudioProcessing::kNoError; |
| 571 } | 504 } |
| 572 } | 505 } |
| 573 return error; | 506 return error; |
| 574 } | 507 } |
| 575 | 508 |
| 576 size_t EchoCancellationImpl::NumCancellersRequired() const { | 509 size_t EchoCancellationImpl::NumCancellersRequired( |
| 577 RTC_DCHECK(stream_properties_); | 510 size_t num_output_channels, |
| 578 return stream_properties_->num_output_channels * | 511 size_t num_reverse_channels) { |
| 579 stream_properties_->num_reverse_channels; | 512 return num_output_channels * num_reverse_channels; |
| 580 } | 513 } |
| 581 | 514 |
| 582 } // namespace webrtc | 515 } // namespace webrtc |
| OLD | NEW |