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

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: Corrected a 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 | « 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
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_GE(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(),
116 audio->split_bands_const_f(j)[kBand0To8kHz], 145 audio->split_bands_const_f(j)[kBand0To8kHz],
117 (audio->split_bands_const_f(j)[kBand0To8kHz] + 146 (audio->split_bands_const_f(j)[kBand0To8kHz] +
118 audio->num_frames_per_band())); 147 audio->num_frames_per_band()));
119
120 handle_index++;
121 } 148 }
122 } 149 }
123 150
124 // Insert the samples into the queue. 151 // Insert the samples into the queue.
125 if (!render_signal_queue_->Insert(&render_queue_buffer_)) { 152 if (!render_signal_queue_->Insert(&render_queue_buffer_)) {
126 // The data queue is full and needs to be emptied. 153 // The data queue is full and needs to be emptied.
127 ReadQueuedRenderData(); 154 ReadQueuedRenderData();
128 155
129 // Retry the insert (should always work). 156 // Retry the insert (should always work).
130 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); 157 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true);
131 } 158 }
132 159
133 return AudioProcessing::kNoError; 160 return AudioProcessing::kNoError;
134 } 161 }
135 162
136 // 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
137 // 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.
138 void EchoCancellationImpl::ReadQueuedRenderData() { 165 void EchoCancellationImpl::ReadQueuedRenderData() {
139 rtc::CritScope cs_capture(crit_capture_); 166 rtc::CritScope cs_capture(crit_capture_);
140 if (!is_component_enabled()) { 167 if (!enabled_) {
141 return; 168 return;
142 } 169 }
143 170
144 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { 171 while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
145 size_t handle_index = 0; 172 size_t handle_index = 0;
146 size_t buffer_index = 0; 173 size_t buffer_index = 0;
147 const size_t num_frames_per_band = 174 const size_t num_frames_per_band =
148 capture_queue_buffer_.size() / 175 capture_queue_buffer_.size() /
149 (apm_->num_output_channels() * apm_->num_reverse_channels()); 176 (apm_->num_output_channels() * apm_->num_reverse_channels());
150 for (size_t i = 0; i < apm_->num_output_channels(); i++) { 177 for (size_t i = 0; i < apm_->num_output_channels(); i++) {
151 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) { 178 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) {
152 Handle* my_handle = static_cast<Handle*>(handle(handle_index)); 179 Handle* my_handle = cancellers_[handle_index++]->state();
153 WebRtcAec_BufferFarend(my_handle, &capture_queue_buffer_[buffer_index], 180 WebRtcAec_BufferFarend(my_handle, &capture_queue_buffer_[buffer_index],
154 num_frames_per_band); 181 num_frames_per_band);
155 182
156 buffer_index += num_frames_per_band; 183 buffer_index += num_frames_per_band;
157 handle_index++;
158 } 184 }
159 } 185 }
160 } 186 }
161 } 187 }
162 188
163 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) { 189 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) {
164 rtc::CritScope cs_capture(crit_capture_); 190 rtc::CritScope cs_capture(crit_capture_);
165 if (!is_component_enabled()) { 191 if (!enabled_) {
166 return AudioProcessing::kNoError; 192 return AudioProcessing::kNoError;
167 } 193 }
168 194
169 if (!apm_->was_stream_delay_set()) { 195 if (!apm_->was_stream_delay_set()) {
170 return AudioProcessing::kStreamParameterNotSetError; 196 return AudioProcessing::kStreamParameterNotSetError;
171 } 197 }
172 198
173 if (drift_compensation_enabled_ && !was_stream_drift_set_) { 199 if (drift_compensation_enabled_ && !was_stream_drift_set_) {
174 return AudioProcessing::kStreamParameterNotSetError; 200 return AudioProcessing::kStreamParameterNotSetError;
175 } 201 }
176 202
177 assert(audio->num_frames_per_band() <= 160); 203 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
178 assert(audio->num_channels() == apm_->num_proc_channels()); 204 RTC_DCHECK_EQ(audio->num_channels(), apm_->num_proc_channels());
179 205
180 int err = AudioProcessing::kNoError; 206 int err = AudioProcessing::kNoError;
181 207
182 // 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.
183 size_t handle_index = 0; 209 size_t handle_index = 0;
184 stream_has_echo_ = false; 210 stream_has_echo_ = false;
185 for (size_t i = 0; i < audio->num_channels(); i++) { 211 for (size_t i = 0; i < audio->num_channels(); i++) {
186 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) { 212 for (size_t j = 0; j < apm_->num_reverse_channels(); j++) {
187 Handle* my_handle = handle(handle_index); 213 Handle* my_handle = cancellers_[handle_index++]->state();
188 err = WebRtcAec_Process(my_handle, audio->split_bands_const_f(i), 214 err = WebRtcAec_Process(my_handle, audio->split_bands_const_f(i),
189 audio->num_bands(), audio->split_bands_f(i), 215 audio->num_bands(), audio->split_bands_f(i),
190 audio->num_frames_per_band(), 216 audio->num_frames_per_band(),
191 apm_->stream_delay_ms(), stream_drift_samples_); 217 apm_->stream_delay_ms(), stream_drift_samples_);
192 218
193 if (err != AudioProcessing::kNoError) { 219 if (err != AudioProcessing::kNoError) {
194 err = MapError(err); 220 err = MapError(err);
195 // TODO(ajm): Figure out how to return warnings properly. 221 // TODO(ajm): Figure out how to return warnings properly.
196 if (err != AudioProcessing::kBadStreamParameterWarning) { 222 if (err != AudioProcessing::kBadStreamParameterWarning) {
197 return err; 223 return err;
198 } 224 }
199 } 225 }
200 226
201 int status = 0; 227 int status = 0;
202 err = WebRtcAec_get_echo_status(my_handle, &status); 228 err = WebRtcAec_get_echo_status(my_handle, &status);
203 if (err != AudioProcessing::kNoError) { 229 if (err != AudioProcessing::kNoError) {
204 return MapError(err); 230 return MapError(err);
205 } 231 }
206 232
207 if (status == 1) { 233 if (status == 1) {
208 stream_has_echo_ = true; 234 stream_has_echo_ = true;
209 } 235 }
210
211 handle_index++;
212 } 236 }
213 } 237 }
214 238
215 was_stream_drift_set_ = false; 239 was_stream_drift_set_ = false;
216 return AudioProcessing::kNoError; 240 return AudioProcessing::kNoError;
217 } 241 }
218 242
219 int EchoCancellationImpl::Enable(bool enable) { 243 int EchoCancellationImpl::Enable(bool enable) {
220 // Run in a single-threaded manner. 244 // Run in a single-threaded manner.
221 rtc::CritScope cs_render(crit_render_); 245 rtc::CritScope cs_render(crit_render_);
222 rtc::CritScope cs_capture(crit_capture_); 246 rtc::CritScope cs_capture(crit_capture_);
223 // Ensure AEC and AECM are not both enabled. 247 // Ensure AEC and AECM are not both enabled.
224 // The is_enabled call is safe from a deadlock perspective 248 // The is_enabled call is safe from a deadlock perspective
225 // as both locks are already held in the correct order. 249 // as both locks are already held in the correct order.
226 if (enable && apm_->echo_control_mobile()->is_enabled()) { 250 if (enable && apm_->echo_control_mobile()->is_enabled()) {
227 return AudioProcessing::kBadParameterError; 251 return AudioProcessing::kBadParameterError;
228 } 252 }
229 253
230 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;
231 } 261 }
232 262
233 bool EchoCancellationImpl::is_enabled() const { 263 bool EchoCancellationImpl::is_enabled() const {
234 rtc::CritScope cs(crit_capture_); 264 rtc::CritScope cs(crit_capture_);
235 return is_component_enabled(); 265 return enabled_;
236 } 266 }
237 267
238 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) { 268 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) {
239 { 269 {
240 if (MapSetting(level) == -1) { 270 if (MapSetting(level) == -1) {
241 return AudioProcessing::kBadParameterError; 271 return AudioProcessing::kBadParameterError;
242 } 272 }
243 rtc::CritScope cs(crit_capture_); 273 rtc::CritScope cs(crit_capture_);
244 suppression_level_ = level; 274 suppression_level_ = level;
245 } 275 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 } 320 }
291 321
292 // 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
293 // aboue the best way to extend this to multi-channel. 323 // aboue the best way to extend this to multi-channel.
294 int EchoCancellationImpl::GetMetrics(Metrics* metrics) { 324 int EchoCancellationImpl::GetMetrics(Metrics* metrics) {
295 rtc::CritScope cs(crit_capture_); 325 rtc::CritScope cs(crit_capture_);
296 if (metrics == NULL) { 326 if (metrics == NULL) {
297 return AudioProcessing::kNullPointerError; 327 return AudioProcessing::kNullPointerError;
298 } 328 }
299 329
300 if (!is_component_enabled() || !metrics_enabled_) { 330 if (!enabled_ || !metrics_enabled_) {
301 return AudioProcessing::kNotEnabledError; 331 return AudioProcessing::kNotEnabledError;
302 } 332 }
303 333
304 AecMetrics my_metrics; 334 AecMetrics my_metrics;
305 memset(&my_metrics, 0, sizeof(my_metrics)); 335 memset(&my_metrics, 0, sizeof(my_metrics));
306 memset(metrics, 0, sizeof(Metrics)); 336 memset(metrics, 0, sizeof(Metrics));
307 337
308 Handle* my_handle = static_cast<Handle*>(handle(0)); 338 Handle* my_handle = cancellers_[0]->state();
309 int err = WebRtcAec_GetMetrics(my_handle, &my_metrics); 339 int err = WebRtcAec_GetMetrics(my_handle, &my_metrics);
310 if (err != AudioProcessing::kNoError) { 340 if (err != AudioProcessing::kNoError) {
311 return MapError(err); 341 return MapError(err);
312 } 342 }
313 343
314 metrics->residual_echo_return_loss.instant = my_metrics.rerl.instant; 344 metrics->residual_echo_return_loss.instant = my_metrics.rerl.instant;
315 metrics->residual_echo_return_loss.average = my_metrics.rerl.average; 345 metrics->residual_echo_return_loss.average = my_metrics.rerl.average;
316 metrics->residual_echo_return_loss.maximum = my_metrics.rerl.max; 346 metrics->residual_echo_return_loss.maximum = my_metrics.rerl.max;
317 metrics->residual_echo_return_loss.minimum = my_metrics.rerl.min; 347 metrics->residual_echo_return_loss.minimum = my_metrics.rerl.min;
318 348
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std, 407 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std,
378 float* fraction_poor_delays) { 408 float* fraction_poor_delays) {
379 rtc::CritScope cs(crit_capture_); 409 rtc::CritScope cs(crit_capture_);
380 if (median == NULL) { 410 if (median == NULL) {
381 return AudioProcessing::kNullPointerError; 411 return AudioProcessing::kNullPointerError;
382 } 412 }
383 if (std == NULL) { 413 if (std == NULL) {
384 return AudioProcessing::kNullPointerError; 414 return AudioProcessing::kNullPointerError;
385 } 415 }
386 416
387 if (!is_component_enabled() || !delay_logging_enabled_) { 417 if (!enabled_ || !delay_logging_enabled_) {
388 return AudioProcessing::kNotEnabledError; 418 return AudioProcessing::kNotEnabledError;
389 } 419 }
390 420
391 Handle* my_handle = static_cast<Handle*>(handle(0)); 421 Handle* my_handle = cancellers_[0]->state();
392 const int err = 422 const int err =
393 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays); 423 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays);
394 if (err != AudioProcessing::kNoError) { 424 if (err != AudioProcessing::kNoError) {
395 return MapError(err); 425 return MapError(err);
396 } 426 }
397 427
398 return AudioProcessing::kNoError; 428 return AudioProcessing::kNoError;
399 } 429 }
400 430
401 struct AecCore* EchoCancellationImpl::aec_core() const { 431 struct AecCore* EchoCancellationImpl::aec_core() const {
402 rtc::CritScope cs(crit_capture_); 432 rtc::CritScope cs(crit_capture_);
403 if (!is_component_enabled()) { 433 if (!enabled_) {
404 return NULL; 434 return NULL;
405 } 435 }
406 Handle* my_handle = static_cast<Handle*>(handle(0)); 436 Handle* my_handle = cancellers_[0]->state();
407 return WebRtcAec_aec_core(my_handle); 437 return WebRtcAec_aec_core(my_handle);
408 } 438 }
409 439
410 int EchoCancellationImpl::Initialize() { 440 void EchoCancellationImpl::Initialize() {
411 int err = ProcessingComponent::Initialize(); 441 rtc::CritScope cs_render(crit_render_);
412 { 442 rtc::CritScope cs_capture(crit_capture_);
413 rtc::CritScope cs(crit_capture_); 443 if (!enabled_) {
414 if (err != AudioProcessing::kNoError || !is_component_enabled()) { 444 return;
415 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));
416 } 454 }
417 } 455 }
418 456
457 for (size_t i = 0; i < cancellers_.size(); ++i) {
458 cancellers_[i]->Initialize(sample_rate_hz);
459 }
460
461 Configure();
462
419 AllocateRenderQueue(); 463 AllocateRenderQueue();
420
421 return AudioProcessing::kNoError;
422 } 464 }
423 465
424 int EchoCancellationImpl::GetSystemDelayInSamples() const { 466 int EchoCancellationImpl::GetSystemDelayInSamples() const {
425 rtc::CritScope cs(crit_capture_); 467 rtc::CritScope cs(crit_capture_);
426 RTC_DCHECK(is_component_enabled()); 468 RTC_DCHECK(enabled_);
427 // Report the delay for the first AEC component. 469 // Report the delay for the first AEC component.
428 return WebRtcAec_system_delay( 470 return WebRtcAec_system_delay(
429 WebRtcAec_aec_core(static_cast<Handle*>(handle(0)))); 471 WebRtcAec_aec_core(cancellers_[0]->state()));
430 } 472 }
431 473
432 void EchoCancellationImpl::AllocateRenderQueue() { 474 void EchoCancellationImpl::AllocateRenderQueue() {
433 const size_t new_render_queue_element_max_size = std::max<size_t>( 475 const size_t new_render_queue_element_max_size = std::max<size_t>(
434 static_cast<size_t>(1), 476 static_cast<size_t>(1),
435 kMaxAllowedValuesOfSamplesPerFrame * num_handles_required()); 477 kMaxAllowedValuesOfSamplesPerFrame * num_handles_required());
436 478
437 rtc::CritScope cs_render(crit_render_); 479 rtc::CritScope cs_render(crit_render_);
438 rtc::CritScope cs_capture(crit_capture_); 480 rtc::CritScope cs_capture(crit_capture_);
439 481
(...skipping 19 matching lines...) Expand all
459 void EchoCancellationImpl::SetExtraOptions(const Config& config) { 501 void EchoCancellationImpl::SetExtraOptions(const Config& config) {
460 { 502 {
461 rtc::CritScope cs(crit_capture_); 503 rtc::CritScope cs(crit_capture_);
462 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; 504 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled;
463 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; 505 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled;
464 next_generation_aec_enabled_ = config.Get<NextGenerationAec>().enabled; 506 next_generation_aec_enabled_ = config.Get<NextGenerationAec>().enabled;
465 } 507 }
466 Configure(); 508 Configure();
467 } 509 }
468 510
469 void* EchoCancellationImpl::CreateHandle() const { 511 int EchoCancellationImpl::Configure() {
470 return WebRtcAec_Create();
471 }
472
473 void EchoCancellationImpl::DestroyHandle(void* handle) const {
474 assert(handle != NULL);
475 WebRtcAec_Free(static_cast<Handle*>(handle));
476 }
477
478 int EchoCancellationImpl::InitializeHandle(void* handle) const {
479 // Not locked as it only relies on APM public API which is threadsafe.
480
481 assert(handle != NULL);
482 // TODO(ajm): Drift compensation is disabled in practice. If restored, it
483 // should be managed internally and not depend on the hardware sample rate.
484 // For now, just hardcode a 48 kHz value.
485 return WebRtcAec_Init(static_cast<Handle*>(handle),
486 apm_->proc_sample_rate_hz(), 48000);
487 }
488
489 int EchoCancellationImpl::ConfigureHandle(void* handle) const {
490 rtc::CritScope cs_render(crit_render_); 512 rtc::CritScope cs_render(crit_render_);
491 rtc::CritScope cs_capture(crit_capture_); 513 rtc::CritScope cs_capture(crit_capture_);
492 assert(handle != NULL);
493 AecConfig config; 514 AecConfig config;
494 config.metricsMode = metrics_enabled_; 515 config.metricsMode = metrics_enabled_;
495 config.nlpMode = MapSetting(suppression_level_); 516 config.nlpMode = MapSetting(suppression_level_);
496 config.skewMode = drift_compensation_enabled_; 517 config.skewMode = drift_compensation_enabled_;
497 config.delay_logging = delay_logging_enabled_; 518 config.delay_logging = delay_logging_enabled_;
498 WebRtcAec_enable_extended_filter( 519
499 WebRtcAec_aec_core(static_cast<Handle*>(handle)), 520 int error = AudioProcessing::kNoError;
500 extended_filter_enabled_ ? 1 : 0); 521 for (size_t i = 0; i < cancellers_.size(); i++) {
501 WebRtcAec_enable_delay_agnostic( 522 Handle* my_handle = cancellers_[i]->state();
502 WebRtcAec_aec_core(static_cast<Handle*>(handle)), 523 WebRtcAec_enable_extended_filter(WebRtcAec_aec_core(my_handle),
503 delay_agnostic_enabled_ ? 1 : 0); 524 extended_filter_enabled_ ? 1 : 0);
504 WebRtcAec_enable_next_generation_aec( 525 WebRtcAec_enable_delay_agnostic(WebRtcAec_aec_core(my_handle),
505 WebRtcAec_aec_core(static_cast<Handle*>(handle)), 526 delay_agnostic_enabled_ ? 1 : 0);
506 next_generation_aec_enabled_ ? 1 : 0); 527 WebRtcAec_enable_next_generation_aec(WebRtcAec_aec_core(my_handle),
507 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); 528 next_generation_aec_enabled_ ? 1 : 0);
529 const int handle_error = WebRtcAec_set_config(my_handle, config);
530 if (handle_error != AudioProcessing::kNoError) {
531 error = AudioProcessing::kNoError;
532 }
533 }
534 return error;
508 } 535 }
509 536
510 size_t EchoCancellationImpl::num_handles_required() const { 537 size_t EchoCancellationImpl::num_handles_required() const {
511 // Not locked as it only relies on APM public API which is threadsafe. 538 // Not locked as it only relies on APM public API which is threadsafe.
512 return apm_->num_output_channels() * apm_->num_reverse_channels(); 539 return apm_->num_output_channels() * apm_->num_reverse_channels();
513 } 540 }
514 541
515 int EchoCancellationImpl::GetHandleError(void* handle) const {
516 // Not locked as it does not rely on anything in the state.
517 assert(handle != NULL);
518 return AudioProcessing::kUnspecifiedError;
519 }
520 } // namespace webrtc 542 } // 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