Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: webrtc/modules/audio_processing/echo_cancellation_impl.cc

Issue 2427553003: Moved the AEC render sample queue into the audio processing module (Closed)
Patch Set: Rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/audio_processing/echo_cancellation_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/echo_cancellation_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698