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

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

Issue 1764293002: Revert of Removed the inheritance from ProcessingComponent for EchoCancellerImpl. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: 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 | « 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 } 52 }
53 53
54 // Maximum length that a frame of samples can have. 54 // Maximum length that a frame of samples can have.
55 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160; 55 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160;
56 // Maximum number of frames to buffer in the render queue. 56 // Maximum number of frames to buffer in the render queue.
57 // TODO(peah): Decrease this once we properly handle hugely unbalanced 57 // TODO(peah): Decrease this once we properly handle hugely unbalanced
58 // reverse and forward call numbers. 58 // reverse and forward call numbers.
59 static const size_t kMaxNumFramesToBuffer = 100; 59 static const size_t kMaxNumFramesToBuffer = 100;
60 } // namespace 60 } // namespace
61 61
62 class EchoCancellationImpl::Canceller {
63 public:
64 explicit Canceller(int sample_rate_hz) {
65 state_ = WebRtcAec_Create();
66 RTC_DCHECK(state_);
67 }
68
69 ~Canceller() {
70 RTC_CHECK(state_);
71 WebRtcAec_Free(state_);
72 }
73
74 Handle* state() { return state_; }
75
76 void Initialize(int sample_rate_hz) {
77 // TODO(ajm): Drift compensation is disabled in practice. If restored, it
78 // should be managed internally and not depend on the hardware sample rate.
79 // For now, just hardcode a 48 kHz value.
80 const int error = WebRtcAec_Init(state_, sample_rate_hz, 48000);
81 RTC_DCHECK_EQ(0, error);
82 }
83
84 private:
85 Handle* state_;
86
87 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Canceller);
88 };
89
90 EchoCancellationImpl::EchoCancellationImpl(const AudioProcessing* apm, 62 EchoCancellationImpl::EchoCancellationImpl(const AudioProcessing* apm,
91 rtc::CriticalSection* crit_render, 63 rtc::CriticalSection* crit_render,
92 rtc::CriticalSection* crit_capture) 64 rtc::CriticalSection* crit_capture)
93 : apm_(apm), 65 : ProcessingComponent(),
66 apm_(apm),
94 crit_render_(crit_render), 67 crit_render_(crit_render),
95 crit_capture_(crit_capture), 68 crit_capture_(crit_capture),
96 drift_compensation_enabled_(false), 69 drift_compensation_enabled_(false),
97 metrics_enabled_(false), 70 metrics_enabled_(false),
98 suppression_level_(kModerateSuppression), 71 suppression_level_(kModerateSuppression),
99 stream_drift_samples_(0), 72 stream_drift_samples_(0),
100 was_stream_drift_set_(false), 73 was_stream_drift_set_(false),
101 stream_has_echo_(false), 74 stream_has_echo_(false),
102 delay_logging_enabled_(false), 75 delay_logging_enabled_(false),
103 extended_filter_enabled_(false), 76 extended_filter_enabled_(false),
104 delay_agnostic_enabled_(false), 77 delay_agnostic_enabled_(false),
105 next_generation_aec_enabled_(false), 78 next_generation_aec_enabled_(false),
106 render_queue_element_max_size_(0) { 79 render_queue_element_max_size_(0) {
107 RTC_DCHECK(apm); 80 RTC_DCHECK(apm);
108 RTC_DCHECK(crit_render); 81 RTC_DCHECK(crit_render);
109 RTC_DCHECK(crit_capture); 82 RTC_DCHECK(crit_capture);
110 } 83 }
111 84
112 EchoCancellationImpl::~EchoCancellationImpl() {} 85 EchoCancellationImpl::~EchoCancellationImpl() {}
113 86
114 int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) { 87 int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) {
115 rtc::CritScope cs_render(crit_render_); 88 rtc::CritScope cs_render(crit_render_);
116 if (!enabled_) { 89 if (!is_component_enabled()) {
117 return AudioProcessing::kNoError; 90 return AudioProcessing::kNoError;
118 } 91 }
119 92
120 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); 93 assert(audio->num_frames_per_band() <= 160);
121 RTC_DCHECK_EQ(audio->num_channels(), apm_->num_reverse_channels()); 94 assert(audio->num_channels() == apm_->num_reverse_channels());
122 RTC_DCHECK_GE(cancellers_.size(),
123 apm_->num_output_channels() * audio->num_channels());
124 95
125 int err = AudioProcessing::kNoError; 96 int err = AudioProcessing::kNoError;
126 97
127 // The ordering convention must be followed to pass to the correct AEC. 98 // The ordering convention must be followed to pass to the correct AEC.
128 size_t handle_index = 0; 99 size_t handle_index = 0;
129 render_queue_buffer_.clear(); 100 render_queue_buffer_.clear();
130 for (size_t i = 0; i < apm_->num_output_channels(); i++) { 101 for (size_t i = 0; i < apm_->num_output_channels(); i++) {
131 for (size_t j = 0; j < audio->num_channels(); j++) { 102 for (size_t j = 0; j < audio->num_channels(); j++) {
132 Handle* my_handle = cancellers_[handle_index++]->state(); 103 Handle* my_handle = static_cast<Handle*>(handle(handle_index));
133 // Retrieve any error code produced by the buffering of the farend 104 // Retrieve any error code produced by the buffering of the farend
134 // signal. 105 // signal
135 err = WebRtcAec_GetBufferFarendError( 106 err = WebRtcAec_GetBufferFarendError(
136 my_handle, audio->split_bands_const_f(j)[kBand0To8kHz], 107 my_handle, audio->split_bands_const_f(j)[kBand0To8kHz],
137 audio->num_frames_per_band()); 108 audio->num_frames_per_band());
138 109
139 if (err != AudioProcessing::kNoError) { 110 if (err != AudioProcessing::kNoError) {
140 return MapError(err); // TODO(ajm): warning possible? 111 return MapError(err); // TODO(ajm): warning possible?
141 } 112 }
142 113
143 // Buffer the samples in the render queue. 114 // Buffer the samples in the render queue.
144 render_queue_buffer_.insert(render_queue_buffer_.end(), 115 render_queue_buffer_.insert(render_queue_buffer_.end(),
145 audio->split_bands_const_f(j)[kBand0To8kHz], 116 audio->split_bands_const_f(j)[kBand0To8kHz],
146 (audio->split_bands_const_f(j)[kBand0To8kHz] + 117 (audio->split_bands_const_f(j)[kBand0To8kHz] +
147 audio->num_frames_per_band())); 118 audio->num_frames_per_band()));
119
120 handle_index++;
148 } 121 }
149 } 122 }
150 123
151 // Insert the samples into the queue. 124 // Insert the samples into the queue.
152 if (!render_signal_queue_->Insert(&render_queue_buffer_)) { 125 if (!render_signal_queue_->Insert(&render_queue_buffer_)) {
153 // The data queue is full and needs to be emptied. 126 // The data queue is full and needs to be emptied.
154 ReadQueuedRenderData(); 127 ReadQueuedRenderData();
155 128
156 // Retry the insert (should always work). 129 // Retry the insert (should always work).
157 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); 130 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true);
158 } 131 }
159 132
160 return AudioProcessing::kNoError; 133 return AudioProcessing::kNoError;
161 } 134 }
162 135
163 // Read chunks of data that were received and queued on the render side from 136 // Read chunks of data that were received and queued on the render side from
164 // a queue. All the data chunks are buffered into the farend signal of the AEC. 137 // a queue. All the data chunks are buffered into the farend signal of the AEC.
165 void EchoCancellationImpl::ReadQueuedRenderData() { 138 void EchoCancellationImpl::ReadQueuedRenderData() {
166 rtc::CritScope cs_capture(crit_capture_); 139 rtc::CritScope cs_capture(crit_capture_);
167 if (!enabled_) { 140 if (!is_component_enabled()) {
168 return; 141 return;
169 } 142 }
170 143
171 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { 144 while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
172 size_t handle_index = 0; 145 size_t handle_index = 0;
173 size_t buffer_index = 0; 146 size_t buffer_index = 0;
174 const size_t num_frames_per_band = 147 const size_t num_frames_per_band =
175 capture_queue_buffer_.size() / 148 capture_queue_buffer_.size() /
176 (apm_->num_output_channels() * apm_->num_reverse_channels()); 149 (apm_->num_output_channels() * apm_->num_reverse_channels());
177 for (size_t i = 0; i < apm_->num_output_channels(); i++) { 150 for (size_t i = 0; i < apm_->num_output_channels(); i++) {
178 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) { 151 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) {
179 Handle* my_handle = cancellers_[handle_index++]->state(); 152 Handle* my_handle = static_cast<Handle*>(handle(handle_index));
180 WebRtcAec_BufferFarend(my_handle, &capture_queue_buffer_[buffer_index], 153 WebRtcAec_BufferFarend(my_handle, &capture_queue_buffer_[buffer_index],
181 num_frames_per_band); 154 num_frames_per_band);
182 155
183 buffer_index += num_frames_per_band; 156 buffer_index += num_frames_per_band;
157 handle_index++;
184 } 158 }
185 } 159 }
186 } 160 }
187 } 161 }
188 162
189 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) { 163 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) {
190 rtc::CritScope cs_capture(crit_capture_); 164 rtc::CritScope cs_capture(crit_capture_);
191 if (!enabled_) { 165 if (!is_component_enabled()) {
192 return AudioProcessing::kNoError; 166 return AudioProcessing::kNoError;
193 } 167 }
194 168
195 if (!apm_->was_stream_delay_set()) { 169 if (!apm_->was_stream_delay_set()) {
196 return AudioProcessing::kStreamParameterNotSetError; 170 return AudioProcessing::kStreamParameterNotSetError;
197 } 171 }
198 172
199 if (drift_compensation_enabled_ && !was_stream_drift_set_) { 173 if (drift_compensation_enabled_ && !was_stream_drift_set_) {
200 return AudioProcessing::kStreamParameterNotSetError; 174 return AudioProcessing::kStreamParameterNotSetError;
201 } 175 }
202 176
203 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); 177 assert(audio->num_frames_per_band() <= 160);
204 RTC_DCHECK_EQ(audio->num_channels(), apm_->num_proc_channels()); 178 assert(audio->num_channels() == apm_->num_proc_channels());
205 179
206 int err = AudioProcessing::kNoError; 180 int err = AudioProcessing::kNoError;
207 181
208 // The ordering convention must be followed to pass to the correct AEC. 182 // The ordering convention must be followed to pass to the correct AEC.
209 size_t handle_index = 0; 183 size_t handle_index = 0;
210 stream_has_echo_ = false; 184 stream_has_echo_ = false;
211 for (size_t i = 0; i < audio->num_channels(); i++) { 185 for (size_t i = 0; i < audio->num_channels(); i++) {
212 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) { 186 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) {
213 Handle* my_handle = cancellers_[handle_index++]->state(); 187 Handle* my_handle = handle(handle_index);
214 err = WebRtcAec_Process(my_handle, audio->split_bands_const_f(i), 188 err = WebRtcAec_Process(my_handle, audio->split_bands_const_f(i),
215 audio->num_bands(), audio->split_bands_f(i), 189 audio->num_bands(), audio->split_bands_f(i),
216 audio->num_frames_per_band(), 190 audio->num_frames_per_band(),
217 apm_->stream_delay_ms(), stream_drift_samples_); 191 apm_->stream_delay_ms(), stream_drift_samples_);
218 192
219 if (err != AudioProcessing::kNoError) { 193 if (err != AudioProcessing::kNoError) {
220 err = MapError(err); 194 err = MapError(err);
221 // TODO(ajm): Figure out how to return warnings properly. 195 // TODO(ajm): Figure out how to return warnings properly.
222 if (err != AudioProcessing::kBadStreamParameterWarning) { 196 if (err != AudioProcessing::kBadStreamParameterWarning) {
223 return err; 197 return err;
224 } 198 }
225 } 199 }
226 200
227 int status = 0; 201 int status = 0;
228 err = WebRtcAec_get_echo_status(my_handle, &status); 202 err = WebRtcAec_get_echo_status(my_handle, &status);
229 if (err != AudioProcessing::kNoError) { 203 if (err != AudioProcessing::kNoError) {
230 return MapError(err); 204 return MapError(err);
231 } 205 }
232 206
233 if (status == 1) { 207 if (status == 1) {
234 stream_has_echo_ = true; 208 stream_has_echo_ = true;
235 } 209 }
210
211 handle_index++;
236 } 212 }
237 } 213 }
238 214
239 was_stream_drift_set_ = false; 215 was_stream_drift_set_ = false;
240 return AudioProcessing::kNoError; 216 return AudioProcessing::kNoError;
241 } 217 }
242 218
243 int EchoCancellationImpl::Enable(bool enable) { 219 int EchoCancellationImpl::Enable(bool enable) {
244 // Run in a single-threaded manner. 220 // Run in a single-threaded manner.
245 rtc::CritScope cs_render(crit_render_); 221 rtc::CritScope cs_render(crit_render_);
246 rtc::CritScope cs_capture(crit_capture_); 222 rtc::CritScope cs_capture(crit_capture_);
247 // Ensure AEC and AECM are not both enabled. 223 // Ensure AEC and AECM are not both enabled.
248 // The is_enabled call is safe from a deadlock perspective 224 // The is_enabled call is safe from a deadlock perspective
249 // as both locks are already held in the correct order. 225 // as both locks are already held in the correct order.
250 if (enable && apm_->echo_control_mobile()->is_enabled()) { 226 if (enable && apm_->echo_control_mobile()->is_enabled()) {
251 return AudioProcessing::kBadParameterError; 227 return AudioProcessing::kBadParameterError;
252 } 228 }
253 229
254 if (enable && !enabled_) { 230 return EnableComponent(enable);
255 enabled_ = enable; // Must be set before Initialize() is called.
256 Initialize();
257 } else {
258 enabled_ = enable;
259 }
260 return AudioProcessing::kNoError;
261 } 231 }
262 232
263 bool EchoCancellationImpl::is_enabled() const { 233 bool EchoCancellationImpl::is_enabled() const {
264 rtc::CritScope cs(crit_capture_); 234 rtc::CritScope cs(crit_capture_);
265 return enabled_; 235 return is_component_enabled();
266 } 236 }
267 237
268 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) { 238 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) {
269 { 239 {
270 if (MapSetting(level) == -1) { 240 if (MapSetting(level) == -1) {
271 return AudioProcessing::kBadParameterError; 241 return AudioProcessing::kBadParameterError;
272 } 242 }
273 rtc::CritScope cs(crit_capture_); 243 rtc::CritScope cs(crit_capture_);
274 suppression_level_ = level; 244 suppression_level_ = level;
275 } 245 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 290 }
321 291
322 // TODO(ajm): we currently just use the metrics from the first AEC. Think more 292 // TODO(ajm): we currently just use the metrics from the first AEC. Think more
323 // aboue the best way to extend this to multi-channel. 293 // aboue the best way to extend this to multi-channel.
324 int EchoCancellationImpl::GetMetrics(Metrics* metrics) { 294 int EchoCancellationImpl::GetMetrics(Metrics* metrics) {
325 rtc::CritScope cs(crit_capture_); 295 rtc::CritScope cs(crit_capture_);
326 if (metrics == NULL) { 296 if (metrics == NULL) {
327 return AudioProcessing::kNullPointerError; 297 return AudioProcessing::kNullPointerError;
328 } 298 }
329 299
330 if (!enabled_ || !metrics_enabled_) { 300 if (!is_component_enabled() || !metrics_enabled_) {
331 return AudioProcessing::kNotEnabledError; 301 return AudioProcessing::kNotEnabledError;
332 } 302 }
333 303
334 AecMetrics my_metrics; 304 AecMetrics my_metrics;
335 memset(&my_metrics, 0, sizeof(my_metrics)); 305 memset(&my_metrics, 0, sizeof(my_metrics));
336 memset(metrics, 0, sizeof(Metrics)); 306 memset(metrics, 0, sizeof(Metrics));
337 307
338 Handle* my_handle = cancellers_[0]->state(); 308 Handle* my_handle = static_cast<Handle*>(handle(0));
339 int err = WebRtcAec_GetMetrics(my_handle, &my_metrics); 309 int err = WebRtcAec_GetMetrics(my_handle, &my_metrics);
340 if (err != AudioProcessing::kNoError) { 310 if (err != AudioProcessing::kNoError) {
341 return MapError(err); 311 return MapError(err);
342 } 312 }
343 313
344 metrics->residual_echo_return_loss.instant = my_metrics.rerl.instant; 314 metrics->residual_echo_return_loss.instant = my_metrics.rerl.instant;
345 metrics->residual_echo_return_loss.average = my_metrics.rerl.average; 315 metrics->residual_echo_return_loss.average = my_metrics.rerl.average;
346 metrics->residual_echo_return_loss.maximum = my_metrics.rerl.max; 316 metrics->residual_echo_return_loss.maximum = my_metrics.rerl.max;
347 metrics->residual_echo_return_loss.minimum = my_metrics.rerl.min; 317 metrics->residual_echo_return_loss.minimum = my_metrics.rerl.min;
348 318
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std, 377 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std,
408 float* fraction_poor_delays) { 378 float* fraction_poor_delays) {
409 rtc::CritScope cs(crit_capture_); 379 rtc::CritScope cs(crit_capture_);
410 if (median == NULL) { 380 if (median == NULL) {
411 return AudioProcessing::kNullPointerError; 381 return AudioProcessing::kNullPointerError;
412 } 382 }
413 if (std == NULL) { 383 if (std == NULL) {
414 return AudioProcessing::kNullPointerError; 384 return AudioProcessing::kNullPointerError;
415 } 385 }
416 386
417 if (!enabled_ || !delay_logging_enabled_) { 387 if (!is_component_enabled() || !delay_logging_enabled_) {
418 return AudioProcessing::kNotEnabledError; 388 return AudioProcessing::kNotEnabledError;
419 } 389 }
420 390
421 Handle* my_handle = cancellers_[0]->state(); 391 Handle* my_handle = static_cast<Handle*>(handle(0));
422 const int err = 392 const int err =
423 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays); 393 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays);
424 if (err != AudioProcessing::kNoError) { 394 if (err != AudioProcessing::kNoError) {
425 return MapError(err); 395 return MapError(err);
426 } 396 }
427 397
428 return AudioProcessing::kNoError; 398 return AudioProcessing::kNoError;
429 } 399 }
430 400
431 struct AecCore* EchoCancellationImpl::aec_core() const { 401 struct AecCore* EchoCancellationImpl::aec_core() const {
432 rtc::CritScope cs(crit_capture_); 402 rtc::CritScope cs(crit_capture_);
433 if (!enabled_) { 403 if (!is_component_enabled()) {
434 return NULL; 404 return NULL;
435 } 405 }
436 Handle* my_handle = cancellers_[0]->state(); 406 Handle* my_handle = static_cast<Handle*>(handle(0));
437 return WebRtcAec_aec_core(my_handle); 407 return WebRtcAec_aec_core(my_handle);
438 } 408 }
439 409
440 void EchoCancellationImpl::Initialize() { 410 int EchoCancellationImpl::Initialize() {
441 rtc::CritScope cs_render(crit_render_); 411 int err = ProcessingComponent::Initialize();
442 rtc::CritScope cs_capture(crit_capture_); 412 {
443 if (!enabled_) { 413 rtc::CritScope cs(crit_capture_);
444 return; 414 if (err != AudioProcessing::kNoError || !is_component_enabled()) {
445 } 415 return err;
446 const int sample_rate_hz = apm_->proc_sample_rate_hz();
447
448 if (num_handles_required() > cancellers_.size()) {
449 const size_t cancellers_old_size = cancellers_.size();
450 cancellers_.resize(num_handles_required());
451
452 for (size_t i = cancellers_old_size; i < cancellers_.size(); ++i) {
453 cancellers_[i].reset(new Canceller(sample_rate_hz));
454 } 416 }
455 } 417 }
456 418
457 for (size_t i = 0; i < cancellers_.size(); ++i) { 419 AllocateRenderQueue();
458 cancellers_[i]->Initialize(sample_rate_hz);
459 }
460 420
461 Configure(); 421 return AudioProcessing::kNoError;
462
463 AllocateRenderQueue();
464 } 422 }
465 423
466 void EchoCancellationImpl::AllocateRenderQueue() { 424 void EchoCancellationImpl::AllocateRenderQueue() {
467 const size_t new_render_queue_element_max_size = std::max<size_t>( 425 const size_t new_render_queue_element_max_size = std::max<size_t>(
468 static_cast<size_t>(1), 426 static_cast<size_t>(1),
469 kMaxAllowedValuesOfSamplesPerFrame * num_handles_required()); 427 kMaxAllowedValuesOfSamplesPerFrame * num_handles_required());
470 428
471 rtc::CritScope cs_render(crit_render_); 429 rtc::CritScope cs_render(crit_render_);
472 rtc::CritScope cs_capture(crit_capture_); 430 rtc::CritScope cs_capture(crit_capture_);
473 431
(...skipping 19 matching lines...) Expand all
493 void EchoCancellationImpl::SetExtraOptions(const Config& config) { 451 void EchoCancellationImpl::SetExtraOptions(const Config& config) {
494 { 452 {
495 rtc::CritScope cs(crit_capture_); 453 rtc::CritScope cs(crit_capture_);
496 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; 454 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled;
497 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; 455 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled;
498 next_generation_aec_enabled_ = config.Get<NextGenerationAec>().enabled; 456 next_generation_aec_enabled_ = config.Get<NextGenerationAec>().enabled;
499 } 457 }
500 Configure(); 458 Configure();
501 } 459 }
502 460
503 int EchoCancellationImpl::Configure() { 461 void* EchoCancellationImpl::CreateHandle() const {
462 return WebRtcAec_Create();
463 }
464
465 void EchoCancellationImpl::DestroyHandle(void* handle) const {
466 assert(handle != NULL);
467 WebRtcAec_Free(static_cast<Handle*>(handle));
468 }
469
470 int EchoCancellationImpl::InitializeHandle(void* handle) const {
471 // Not locked as it only relies on APM public API which is threadsafe.
472
473 assert(handle != NULL);
474 // TODO(ajm): Drift compensation is disabled in practice. If restored, it
475 // should be managed internally and not depend on the hardware sample rate.
476 // For now, just hardcode a 48 kHz value.
477 return WebRtcAec_Init(static_cast<Handle*>(handle),
478 apm_->proc_sample_rate_hz(), 48000);
479 }
480
481 int EchoCancellationImpl::ConfigureHandle(void* handle) const {
504 rtc::CritScope cs_render(crit_render_); 482 rtc::CritScope cs_render(crit_render_);
505 rtc::CritScope cs_capture(crit_capture_); 483 rtc::CritScope cs_capture(crit_capture_);
484 assert(handle != NULL);
506 AecConfig config; 485 AecConfig config;
507 config.metricsMode = metrics_enabled_; 486 config.metricsMode = metrics_enabled_;
508 config.nlpMode = MapSetting(suppression_level_); 487 config.nlpMode = MapSetting(suppression_level_);
509 config.skewMode = drift_compensation_enabled_; 488 config.skewMode = drift_compensation_enabled_;
510 config.delay_logging = delay_logging_enabled_; 489 config.delay_logging = delay_logging_enabled_;
511 490 WebRtcAec_enable_extended_filter(
512 int error = AudioProcessing::kNoError; 491 WebRtcAec_aec_core(static_cast<Handle*>(handle)),
513 for (size_t i = 0; i < cancellers_.size(); i++) { 492 extended_filter_enabled_ ? 1 : 0);
514 Handle* my_handle = cancellers_[i]->state(); 493 WebRtcAec_enable_delay_agnostic(
515 WebRtcAec_enable_extended_filter(WebRtcAec_aec_core(my_handle), 494 WebRtcAec_aec_core(static_cast<Handle*>(handle)),
516 extended_filter_enabled_ ? 1 : 0); 495 delay_agnostic_enabled_ ? 1 : 0);
517 WebRtcAec_enable_delay_agnostic(WebRtcAec_aec_core(my_handle), 496 WebRtcAec_enable_next_generation_aec(
518 delay_agnostic_enabled_ ? 1 : 0); 497 WebRtcAec_aec_core(static_cast<Handle*>(handle)),
519 WebRtcAec_enable_next_generation_aec(WebRtcAec_aec_core(my_handle), 498 next_generation_aec_enabled_ ? 1 : 0);
520 next_generation_aec_enabled_ ? 1 : 0); 499 return WebRtcAec_set_config(static_cast<Handle*>(handle), config);
521 const int handle_error = WebRtcAec_set_config(my_handle, config);
522 if (handle_error != AudioProcessing::kNoError) {
523 error = AudioProcessing::kNoError;
524 }
525 }
526 return error;
527 } 500 }
528 501
529 size_t EchoCancellationImpl::num_handles_required() const { 502 size_t EchoCancellationImpl::num_handles_required() const {
530 // Not locked as it only relies on APM public API which is threadsafe. 503 // Not locked as it only relies on APM public API which is threadsafe.
531 return apm_->num_output_channels() * apm_->num_reverse_channels(); 504 return apm_->num_output_channels() * apm_->num_reverse_channels();
532 } 505 }
533 506
507 int EchoCancellationImpl::GetHandleError(void* handle) const {
508 // Not locked as it does not rely on anything in the state.
509 assert(handle != NULL);
510 return AudioProcessing::kUnspecifiedError;
511 }
534 } // namespace webrtc 512 } // 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