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 |