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

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

Issue 1767043002: Minor cleaning up of the EchoCancellationImpl code (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixed bad merge Created 4 years, 9 months 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 | « no previous file | 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
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 #include "webrtc/modules/audio_processing/aec/aec_core.h" 16 #include "webrtc/modules/audio_processing/aec/aec_core.h"
17 #include "webrtc/modules/audio_processing/aec/echo_cancellation.h" 17 #include "webrtc/modules/audio_processing/aec/echo_cancellation.h"
18 #include "webrtc/modules/audio_processing/audio_buffer.h" 18 #include "webrtc/modules/audio_processing/audio_buffer.h"
19 19
20 namespace webrtc { 20 namespace webrtc {
21 21
22 typedef void Handle;
23
24 namespace { 22 namespace {
25 int16_t MapSetting(EchoCancellation::SuppressionLevel level) { 23 int16_t MapSetting(EchoCancellation::SuppressionLevel level) {
26 switch (level) { 24 switch (level) {
27 case EchoCancellation::kLowSuppression: 25 case EchoCancellation::kLowSuppression:
28 return kAecNlpConservative; 26 return kAecNlpConservative;
29 case EchoCancellation::kModerateSuppression: 27 case EchoCancellation::kModerateSuppression:
30 return kAecNlpModerate; 28 return kAecNlpModerate;
31 case EchoCancellation::kHighSuppression: 29 case EchoCancellation::kHighSuppression:
32 return kAecNlpAggressive; 30 return kAecNlpAggressive;
33 } 31 }
(...skipping 20 matching lines...) Expand all
54 // Maximum length that a frame of samples can have. 52 // Maximum length that a frame of samples can have.
55 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160; 53 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160;
56 // Maximum number of frames to buffer in the render queue. 54 // Maximum number of frames to buffer in the render queue.
57 // TODO(peah): Decrease this once we properly handle hugely unbalanced 55 // TODO(peah): Decrease this once we properly handle hugely unbalanced
58 // reverse and forward call numbers. 56 // reverse and forward call numbers.
59 static const size_t kMaxNumFramesToBuffer = 100; 57 static const size_t kMaxNumFramesToBuffer = 100;
60 } // namespace 58 } // namespace
61 59
62 class EchoCancellationImpl::Canceller { 60 class EchoCancellationImpl::Canceller {
63 public: 61 public:
64 explicit Canceller(int sample_rate_hz) { 62 Canceller() {
65 state_ = WebRtcAec_Create(); 63 state_ = WebRtcAec_Create();
66 RTC_DCHECK(state_); 64 RTC_DCHECK(state_);
67 } 65 }
68 66
69 ~Canceller() { 67 ~Canceller() {
70 RTC_CHECK(state_); 68 RTC_CHECK(state_);
71 WebRtcAec_Free(state_); 69 WebRtcAec_Free(state_);
72 } 70 }
73 71
74 Handle* state() { return state_; } 72 void* state() { return state_; }
75 73
76 void Initialize(int sample_rate_hz) { 74 void Initialize(int sample_rate_hz) {
77 // TODO(ajm): Drift compensation is disabled in practice. If restored, it 75 // TODO(ajm): Drift compensation is disabled in practice. If restored, it
78 // should be managed internally and not depend on the hardware sample rate. 76 // should be managed internally and not depend on the hardware sample rate.
79 // For now, just hardcode a 48 kHz value. 77 // For now, just hardcode a 48 kHz value.
80 const int error = WebRtcAec_Init(state_, sample_rate_hz, 48000); 78 const int error = WebRtcAec_Init(state_, sample_rate_hz, 48000);
81 RTC_DCHECK_EQ(0, error); 79 RTC_DCHECK_EQ(0, error);
82 } 80 }
83 81
84 private: 82 private:
85 Handle* state_; 83 void* state_;
86
87 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Canceller);
88 }; 84 };
89 85
90 EchoCancellationImpl::EchoCancellationImpl(const AudioProcessing* apm, 86 EchoCancellationImpl::EchoCancellationImpl(const AudioProcessing* apm,
91 rtc::CriticalSection* crit_render, 87 rtc::CriticalSection* crit_render,
92 rtc::CriticalSection* crit_capture) 88 rtc::CriticalSection* crit_capture)
93 : apm_(apm), 89 : apm_(apm),
94 crit_render_(crit_render), 90 crit_render_(crit_render),
95 crit_capture_(crit_capture), 91 crit_capture_(crit_capture),
96 drift_compensation_enabled_(false), 92 drift_compensation_enabled_(false),
97 metrics_enabled_(false), 93 metrics_enabled_(false),
(...skipping 24 matching lines...) Expand all
122 RTC_DCHECK_GE(cancellers_.size(), 118 RTC_DCHECK_GE(cancellers_.size(),
123 apm_->num_output_channels() * audio->num_channels()); 119 apm_->num_output_channels() * audio->num_channels());
124 120
125 int err = AudioProcessing::kNoError; 121 int err = AudioProcessing::kNoError;
126 122
127 // The ordering convention must be followed to pass to the correct AEC. 123 // The ordering convention must be followed to pass to the correct AEC.
128 size_t handle_index = 0; 124 size_t handle_index = 0;
129 render_queue_buffer_.clear(); 125 render_queue_buffer_.clear();
130 for (size_t i = 0; i < apm_->num_output_channels(); i++) { 126 for (size_t i = 0; i < apm_->num_output_channels(); i++) {
131 for (size_t j = 0; j < audio->num_channels(); j++) { 127 for (size_t j = 0; j < audio->num_channels(); j++) {
132 Handle* my_handle = cancellers_[handle_index++]->state();
133 // Retrieve any error code produced by the buffering of the farend 128 // Retrieve any error code produced by the buffering of the farend
134 // signal. 129 // signal.
135 err = WebRtcAec_GetBufferFarendError( 130 err = WebRtcAec_GetBufferFarendError(
136 my_handle, audio->split_bands_const_f(j)[kBand0To8kHz], 131 cancellers_[handle_index++]->state(),
132 audio->split_bands_const_f(j)[kBand0To8kHz],
137 audio->num_frames_per_band()); 133 audio->num_frames_per_band());
138 134
139 if (err != AudioProcessing::kNoError) { 135 if (err != AudioProcessing::kNoError) {
140 return MapError(err); // TODO(ajm): warning possible? 136 return MapError(err); // TODO(ajm): warning possible?
141 } 137 }
142 138
143 // Buffer the samples in the render queue. 139 // Buffer the samples in the render queue.
144 render_queue_buffer_.insert(render_queue_buffer_.end(), 140 render_queue_buffer_.insert(render_queue_buffer_.end(),
145 audio->split_bands_const_f(j)[kBand0To8kHz], 141 audio->split_bands_const_f(j)[kBand0To8kHz],
146 (audio->split_bands_const_f(j)[kBand0To8kHz] + 142 (audio->split_bands_const_f(j)[kBand0To8kHz] +
(...skipping 22 matching lines...) Expand all
169 } 165 }
170 166
171 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { 167 while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
172 size_t handle_index = 0; 168 size_t handle_index = 0;
173 size_t buffer_index = 0; 169 size_t buffer_index = 0;
174 const size_t num_frames_per_band = 170 const size_t num_frames_per_band =
175 capture_queue_buffer_.size() / 171 capture_queue_buffer_.size() /
176 (apm_->num_output_channels() * apm_->num_reverse_channels()); 172 (apm_->num_output_channels() * apm_->num_reverse_channels());
177 for (size_t i = 0; i < apm_->num_output_channels(); i++) { 173 for (size_t i = 0; i < apm_->num_output_channels(); i++) {
178 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) { 174 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) {
179 Handle* my_handle = cancellers_[handle_index++]->state(); 175 WebRtcAec_BufferFarend(cancellers_[handle_index++]->state(),
180 WebRtcAec_BufferFarend(my_handle, &capture_queue_buffer_[buffer_index], 176 &capture_queue_buffer_[buffer_index],
181 num_frames_per_band); 177 num_frames_per_band);
182 178
183 buffer_index += num_frames_per_band; 179 buffer_index += num_frames_per_band;
184 } 180 }
185 } 181 }
186 } 182 }
187 } 183 }
188 184
189 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) { 185 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) {
190 rtc::CritScope cs_capture(crit_capture_); 186 rtc::CritScope cs_capture(crit_capture_);
(...skipping 12 matching lines...) Expand all
203 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); 199 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
204 RTC_DCHECK_EQ(audio->num_channels(), apm_->num_proc_channels()); 200 RTC_DCHECK_EQ(audio->num_channels(), apm_->num_proc_channels());
205 201
206 int err = AudioProcessing::kNoError; 202 int err = AudioProcessing::kNoError;
207 203
208 // The ordering convention must be followed to pass to the correct AEC. 204 // The ordering convention must be followed to pass to the correct AEC.
209 size_t handle_index = 0; 205 size_t handle_index = 0;
210 stream_has_echo_ = false; 206 stream_has_echo_ = false;
211 for (size_t i = 0; i < audio->num_channels(); i++) { 207 for (size_t i = 0; i < audio->num_channels(); i++) {
212 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) { 208 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) {
213 Handle* my_handle = cancellers_[handle_index++]->state(); 209 err = WebRtcAec_Process(cancellers_[handle_index]->state(),
214 err = WebRtcAec_Process(my_handle, audio->split_bands_const_f(i), 210 audio->split_bands_const_f(i), audio->num_bands(),
215 audio->num_bands(), audio->split_bands_f(i), 211 audio->split_bands_f(i),
216 audio->num_frames_per_band(), 212 audio->num_frames_per_band(),
217 apm_->stream_delay_ms(), stream_drift_samples_); 213 apm_->stream_delay_ms(), stream_drift_samples_);
218 214
219 if (err != AudioProcessing::kNoError) { 215 if (err != AudioProcessing::kNoError) {
220 err = MapError(err); 216 err = MapError(err);
221 // TODO(ajm): Figure out how to return warnings properly. 217 // TODO(ajm): Figure out how to return warnings properly.
222 if (err != AudioProcessing::kBadStreamParameterWarning) { 218 if (err != AudioProcessing::kBadStreamParameterWarning) {
223 return err; 219 return err;
224 } 220 }
225 } 221 }
226 222
227 int status = 0; 223 int status = 0;
228 err = WebRtcAec_get_echo_status(my_handle, &status); 224 err = WebRtcAec_get_echo_status(cancellers_[handle_index]->state(),
225 &status);
229 if (err != AudioProcessing::kNoError) { 226 if (err != AudioProcessing::kNoError) {
230 return MapError(err); 227 return MapError(err);
231 } 228 }
232 229
233 if (status == 1) { 230 if (status == 1) {
234 stream_has_echo_ = true; 231 stream_has_echo_ = true;
235 } 232 }
233
234 handle_index++;
236 } 235 }
237 } 236 }
238 237
239 was_stream_drift_set_ = false; 238 was_stream_drift_set_ = false;
240 return AudioProcessing::kNoError; 239 return AudioProcessing::kNoError;
241 } 240 }
242 241
243 int EchoCancellationImpl::Enable(bool enable) { 242 int EchoCancellationImpl::Enable(bool enable) {
244 // Run in a single-threaded manner. 243 // Run in a single-threaded manner.
245 rtc::CritScope cs_render(crit_render_); 244 rtc::CritScope cs_render(crit_render_);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 } 327 }
329 328
330 if (!enabled_ || !metrics_enabled_) { 329 if (!enabled_ || !metrics_enabled_) {
331 return AudioProcessing::kNotEnabledError; 330 return AudioProcessing::kNotEnabledError;
332 } 331 }
333 332
334 AecMetrics my_metrics; 333 AecMetrics my_metrics;
335 memset(&my_metrics, 0, sizeof(my_metrics)); 334 memset(&my_metrics, 0, sizeof(my_metrics));
336 memset(metrics, 0, sizeof(Metrics)); 335 memset(metrics, 0, sizeof(Metrics));
337 336
338 Handle* my_handle = cancellers_[0]->state(); 337 const int err = WebRtcAec_GetMetrics(cancellers_[0]->state(), &my_metrics);
339 int err = WebRtcAec_GetMetrics(my_handle, &my_metrics);
340 if (err != AudioProcessing::kNoError) { 338 if (err != AudioProcessing::kNoError) {
341 return MapError(err); 339 return MapError(err);
342 } 340 }
343 341
344 metrics->residual_echo_return_loss.instant = my_metrics.rerl.instant; 342 metrics->residual_echo_return_loss.instant = my_metrics.rerl.instant;
345 metrics->residual_echo_return_loss.average = my_metrics.rerl.average; 343 metrics->residual_echo_return_loss.average = my_metrics.rerl.average;
346 metrics->residual_echo_return_loss.maximum = my_metrics.rerl.max; 344 metrics->residual_echo_return_loss.maximum = my_metrics.rerl.max;
347 metrics->residual_echo_return_loss.minimum = my_metrics.rerl.min; 345 metrics->residual_echo_return_loss.minimum = my_metrics.rerl.min;
348 346
349 metrics->echo_return_loss.instant = my_metrics.erl.instant; 347 metrics->echo_return_loss.instant = my_metrics.erl.instant;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 return AudioProcessing::kNullPointerError; 409 return AudioProcessing::kNullPointerError;
412 } 410 }
413 if (std == NULL) { 411 if (std == NULL) {
414 return AudioProcessing::kNullPointerError; 412 return AudioProcessing::kNullPointerError;
415 } 413 }
416 414
417 if (!enabled_ || !delay_logging_enabled_) { 415 if (!enabled_ || !delay_logging_enabled_) {
418 return AudioProcessing::kNotEnabledError; 416 return AudioProcessing::kNotEnabledError;
419 } 417 }
420 418
421 Handle* my_handle = cancellers_[0]->state(); 419 const int err = WebRtcAec_GetDelayMetrics(cancellers_[0]->state(), median,
422 const int err = 420 std, fraction_poor_delays);
423 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays);
424 if (err != AudioProcessing::kNoError) { 421 if (err != AudioProcessing::kNoError) {
425 return MapError(err); 422 return MapError(err);
426 } 423 }
427 424
428 return AudioProcessing::kNoError; 425 return AudioProcessing::kNoError;
429 } 426 }
430 427
431 struct AecCore* EchoCancellationImpl::aec_core() const { 428 struct AecCore* EchoCancellationImpl::aec_core() const {
432 rtc::CritScope cs(crit_capture_); 429 rtc::CritScope cs(crit_capture_);
433 if (!enabled_) { 430 if (!enabled_) {
434 return NULL; 431 return NULL;
435 } 432 }
436 Handle* my_handle = cancellers_[0]->state(); 433 return WebRtcAec_aec_core(cancellers_[0]->state());
437 return WebRtcAec_aec_core(my_handle);
438 } 434 }
439 435
440 void EchoCancellationImpl::Initialize() { 436 void EchoCancellationImpl::Initialize() {
441 rtc::CritScope cs_render(crit_render_); 437 rtc::CritScope cs_render(crit_render_);
442 rtc::CritScope cs_capture(crit_capture_); 438 rtc::CritScope cs_capture(crit_capture_);
443 if (!enabled_) { 439 if (!enabled_) {
444 return; 440 return;
445 } 441 }
446 const int sample_rate_hz = apm_->proc_sample_rate_hz();
447 442
448 if (num_handles_required() > cancellers_.size()) { 443 if (num_handles_required() > cancellers_.size()) {
449 const size_t cancellers_old_size = cancellers_.size(); 444 const size_t cancellers_old_size = cancellers_.size();
450 cancellers_.resize(num_handles_required()); 445 cancellers_.resize(num_handles_required());
451 446
452 for (size_t i = cancellers_old_size; i < cancellers_.size(); ++i) { 447 for (size_t i = cancellers_old_size; i < cancellers_.size(); ++i) {
453 cancellers_[i].reset(new Canceller(sample_rate_hz)); 448 cancellers_[i].reset(new Canceller());
454 } 449 }
455 } 450 }
456 451
457 for (size_t i = 0; i < cancellers_.size(); ++i) { 452 const int sample_rate_hz = apm_->proc_sample_rate_hz();
458 cancellers_[i]->Initialize(sample_rate_hz); 453 for (auto& canceller : cancellers_) {
454 canceller->Initialize(sample_rate_hz);
459 } 455 }
460 456
461 Configure(); 457 Configure();
462 458
463 AllocateRenderQueue(); 459 AllocateRenderQueue();
464 } 460 }
465 461
466 int EchoCancellationImpl::GetSystemDelayInSamples() const { 462 int EchoCancellationImpl::GetSystemDelayInSamples() const {
467 rtc::CritScope cs(crit_capture_); 463 rtc::CritScope cs(crit_capture_);
468 RTC_DCHECK(enabled_); 464 RTC_DCHECK(enabled_);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 int EchoCancellationImpl::Configure() { 507 int EchoCancellationImpl::Configure() {
512 rtc::CritScope cs_render(crit_render_); 508 rtc::CritScope cs_render(crit_render_);
513 rtc::CritScope cs_capture(crit_capture_); 509 rtc::CritScope cs_capture(crit_capture_);
514 AecConfig config; 510 AecConfig config;
515 config.metricsMode = metrics_enabled_; 511 config.metricsMode = metrics_enabled_;
516 config.nlpMode = MapSetting(suppression_level_); 512 config.nlpMode = MapSetting(suppression_level_);
517 config.skewMode = drift_compensation_enabled_; 513 config.skewMode = drift_compensation_enabled_;
518 config.delay_logging = delay_logging_enabled_; 514 config.delay_logging = delay_logging_enabled_;
519 515
520 int error = AudioProcessing::kNoError; 516 int error = AudioProcessing::kNoError;
521 for (size_t i = 0; i < cancellers_.size(); i++) { 517 for (auto& canceller : cancellers_) {
522 Handle* my_handle = cancellers_[i]->state(); 518 WebRtcAec_enable_extended_filter(WebRtcAec_aec_core(canceller->state()),
523 WebRtcAec_enable_extended_filter(WebRtcAec_aec_core(my_handle),
524 extended_filter_enabled_ ? 1 : 0); 519 extended_filter_enabled_ ? 1 : 0);
525 WebRtcAec_enable_delay_agnostic(WebRtcAec_aec_core(my_handle), 520 WebRtcAec_enable_delay_agnostic(WebRtcAec_aec_core(canceller->state()),
526 delay_agnostic_enabled_ ? 1 : 0); 521 delay_agnostic_enabled_ ? 1 : 0);
527 WebRtcAec_enable_aec3(WebRtcAec_aec_core(my_handle), aec3_enabled_ ? 1 : 0); 522 WebRtcAec_enable_aec3(WebRtcAec_aec_core(canceller->state()),
528 const int handle_error = WebRtcAec_set_config(my_handle, config); 523 aec3_enabled_ ? 1 : 0);
524 const int handle_error = WebRtcAec_set_config(canceller->state(), config);
529 if (handle_error != AudioProcessing::kNoError) { 525 if (handle_error != AudioProcessing::kNoError) {
530 error = AudioProcessing::kNoError; 526 error = AudioProcessing::kNoError;
531 } 527 }
532 } 528 }
533 return error; 529 return error;
534 } 530 }
535 531
536 size_t EchoCancellationImpl::num_handles_required() const { 532 size_t EchoCancellationImpl::num_handles_required() const {
537 // Not locked as it only relies on APM public API which is threadsafe. 533 // Not locked as it only relies on APM public API which is threadsafe.
538 return apm_->num_output_channels() * apm_->num_reverse_channels(); 534 return apm_->num_output_channels() * apm_->num_reverse_channels();
539 } 535 }
540 536
541 } // namespace webrtc 537 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698