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

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

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

Powered by Google App Engine
This is Rietveld 408576698