OLD | NEW |
---|---|
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 apm_(apm), | 61 apm_(apm), |
62 crit_(crit), | 62 crit_(crit), |
63 drift_compensation_enabled_(false), | 63 drift_compensation_enabled_(false), |
64 metrics_enabled_(false), | 64 metrics_enabled_(false), |
65 suppression_level_(kModerateSuppression), | 65 suppression_level_(kModerateSuppression), |
66 stream_drift_samples_(0), | 66 stream_drift_samples_(0), |
67 was_stream_drift_set_(false), | 67 was_stream_drift_set_(false), |
68 stream_has_echo_(false), | 68 stream_has_echo_(false), |
69 delay_logging_enabled_(false), | 69 delay_logging_enabled_(false), |
70 extended_filter_enabled_(false), | 70 extended_filter_enabled_(false), |
71 delay_agnostic_enabled_(false) { | 71 delay_agnostic_enabled_(false), |
72 render_queue_buffer_(kMaxNumSamplesPerFrameToBuffer), | |
73 capture_queue_buffer_(kMaxNumSamplesPerFrameToBuffer) { | |
74 std::vector<float> template_queue_element(kMaxNumSamplesPerFrameToBuffer); | |
75 | |
76 render_signal_queue_.reset( | |
77 new SwapQueue<std::vector<float>, &RenderQueueItemVerifier>( | |
78 (kMaxNumFramesToBuffer * kMaxNumChannelsPerFrameToBuffer), | |
79 template_queue_element)); | |
72 } | 80 } |
73 | 81 |
74 EchoCancellationImpl::~EchoCancellationImpl() {} | 82 EchoCancellationImpl::~EchoCancellationImpl() {} |
75 | 83 |
76 int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) { | 84 int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) { |
77 if (!is_component_enabled()) { | 85 if (!is_component_enabled()) { |
78 return apm_->kNoError; | 86 return apm_->kNoError; |
79 } | 87 } |
80 | 88 |
81 assert(audio->num_frames_per_band() <= 160); | 89 assert(audio->num_frames_per_band() <= 160); |
82 assert(audio->num_channels() == apm_->num_reverse_channels()); | 90 assert(audio->num_channels() == apm_->num_reverse_channels()); |
83 | 91 |
84 int err = apm_->kNoError; | 92 int err = apm_->kNoError; |
85 | 93 |
86 // The ordering convention must be followed to pass to the correct AEC. | 94 // The ordering convention must be followed to pass to the correct AEC. |
87 size_t handle_index = 0; | 95 size_t handle_index = 0; |
88 for (int i = 0; i < apm_->num_output_channels(); i++) { | 96 for (int i = 0; i < apm_->num_output_channels(); i++) { |
89 for (int j = 0; j < audio->num_channels(); j++) { | 97 for (int j = 0; j < audio->num_channels(); j++) { |
90 Handle* my_handle = static_cast<Handle*>(handle(handle_index)); | 98 Handle* my_handle = static_cast<Handle*>(handle(handle_index)); |
91 err = WebRtcAec_BufferFarend( | 99 // Retrieve any error code produced by the buffering of the farend |
92 my_handle, | 100 // signal |
93 audio->split_bands_const_f(j)[kBand0To8kHz], | 101 err = WebRtcAec_GetBufferFarendError( |
102 my_handle, audio->split_bands_const_f(j)[kBand0To8kHz], | |
94 audio->num_frames_per_band()); | 103 audio->num_frames_per_band()); |
95 | 104 |
96 if (err != apm_->kNoError) { | 105 if (err != apm_->kNoError) { |
97 return MapError(err); // TODO(ajm): warning possible? | 106 return MapError(err); // TODO(ajm): warning possible? |
98 } | 107 } |
99 | 108 |
109 // Buffer the samples in the render queue. | |
110 memcpy(&render_queue_buffer_[0], | |
111 audio->split_bands_const_f(j)[kBand0To8kHz], | |
112 (audio->num_frames_per_band() * | |
113 sizeof(*audio->split_bands_const_f(j)[kBand0To8kHz]))); | |
kwiberg-webrtc
2015/10/17 07:50:07
Maybe I just haven't stared long enough, but where
peah-webrtc
2015/10/26 09:03:48
I rewrote this quite a lot. Could you please let m
| |
114 render_queue_buffer_.resize(audio->num_frames_per_band()); | |
kwiberg-webrtc
2015/10/17 07:50:07
Oh, here. This is illegal if it ends up increasing
peah-webrtc
2015/10/26 09:03:48
Agree. It is now rewritten. Could you please reche
| |
115 // TODO(peah): Refactor so that it is possible to check the | |
116 // return value of Insert. Currently, that is not possible | |
117 // due to the code design when the capture thread is never | |
118 // started. | |
kwiberg-webrtc
2015/10/17 07:50:07
Yeah, I guess that has to be done before this CL c
peah-webrtc
2015/10/26 09:03:48
This is also now redesigned. It should be fine now
| |
119 render_signal_queue_->Insert(&render_queue_buffer_); | |
100 handle_index++; | 120 handle_index++; |
101 } | 121 } |
102 } | 122 } |
103 | 123 |
104 return apm_->kNoError; | 124 return apm_->kNoError; |
105 } | 125 } |
106 | 126 |
127 // Read chunks of data that were received and queued on the render side from | |
128 // a queue. All the data chunks are buffered into the farend signal of the AEC. | |
129 void EchoCancellationImpl::ReadQueuedRenderData() { | |
130 if (!is_component_enabled()) { | |
131 return; | |
132 } | |
133 | |
134 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { | |
135 size_t handle_index = 0; | |
136 for (int i = 0; i < apm_->num_output_channels(); i++) { | |
137 for (int j = 0; j < apm_->num_reverse_channels(); j++) { | |
138 Handle* my_handle = static_cast<Handle*>(handle(handle_index)); | |
139 (void)WebRtcAec_BufferFarend(my_handle, &capture_queue_buffer_[0], | |
140 capture_queue_buffer_.size()); | |
141 } | |
142 } | |
143 } | |
144 } | |
145 | |
107 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) { | 146 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio) { |
108 if (!is_component_enabled()) { | 147 if (!is_component_enabled()) { |
109 return apm_->kNoError; | 148 return apm_->kNoError; |
110 } | 149 } |
111 | 150 |
112 if (!apm_->was_stream_delay_set()) { | 151 if (!apm_->was_stream_delay_set()) { |
113 return apm_->kStreamParameterNotSetError; | 152 return apm_->kStreamParameterNotSetError; |
114 } | 153 } |
115 | 154 |
116 if (drift_compensation_enabled_ && !was_stream_drift_set_) { | 155 if (drift_compensation_enabled_ && !was_stream_drift_set_) { |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
321 struct AecCore* EchoCancellationImpl::aec_core() const { | 360 struct AecCore* EchoCancellationImpl::aec_core() const { |
322 CriticalSectionScoped crit_scoped(crit_); | 361 CriticalSectionScoped crit_scoped(crit_); |
323 if (!is_component_enabled()) { | 362 if (!is_component_enabled()) { |
324 return NULL; | 363 return NULL; |
325 } | 364 } |
326 Handle* my_handle = static_cast<Handle*>(handle(0)); | 365 Handle* my_handle = static_cast<Handle*>(handle(0)); |
327 return WebRtcAec_aec_core(my_handle); | 366 return WebRtcAec_aec_core(my_handle); |
328 } | 367 } |
329 | 368 |
330 int EchoCancellationImpl::Initialize() { | 369 int EchoCancellationImpl::Initialize() { |
370 render_signal_queue_->Clear(); | |
331 int err = ProcessingComponent::Initialize(); | 371 int err = ProcessingComponent::Initialize(); |
332 if (err != apm_->kNoError || !is_component_enabled()) { | 372 if (err != apm_->kNoError || !is_component_enabled()) { |
333 return err; | 373 return err; |
334 } | 374 } |
335 | 375 |
336 return apm_->kNoError; | 376 return apm_->kNoError; |
337 } | 377 } |
338 | 378 |
339 void EchoCancellationImpl::SetExtraOptions(const Config& config) { | 379 void EchoCancellationImpl::SetExtraOptions(const Config& config) { |
340 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; | 380 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; |
(...skipping 20 matching lines...) Expand all Loading... | |
361 48000); | 401 48000); |
362 } | 402 } |
363 | 403 |
364 int EchoCancellationImpl::ConfigureHandle(void* handle) const { | 404 int EchoCancellationImpl::ConfigureHandle(void* handle) const { |
365 assert(handle != NULL); | 405 assert(handle != NULL); |
366 AecConfig config; | 406 AecConfig config; |
367 config.metricsMode = metrics_enabled_; | 407 config.metricsMode = metrics_enabled_; |
368 config.nlpMode = MapSetting(suppression_level_); | 408 config.nlpMode = MapSetting(suppression_level_); |
369 config.skewMode = drift_compensation_enabled_; | 409 config.skewMode = drift_compensation_enabled_; |
370 config.delay_logging = delay_logging_enabled_; | 410 config.delay_logging = delay_logging_enabled_; |
371 | |
372 WebRtcAec_enable_extended_filter( | 411 WebRtcAec_enable_extended_filter( |
373 WebRtcAec_aec_core(static_cast<Handle*>(handle)), | 412 WebRtcAec_aec_core(static_cast<Handle*>(handle)), |
374 extended_filter_enabled_ ? 1 : 0); | 413 extended_filter_enabled_ ? 1 : 0); |
375 WebRtcAec_enable_delay_agnostic( | 414 WebRtcAec_enable_delay_agnostic( |
376 WebRtcAec_aec_core(static_cast<Handle*>(handle)), | 415 WebRtcAec_aec_core(static_cast<Handle*>(handle)), |
377 delay_agnostic_enabled_ ? 1 : 0); | 416 delay_agnostic_enabled_ ? 1 : 0); |
378 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); | 417 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); |
379 } | 418 } |
380 | 419 |
381 int EchoCancellationImpl::num_handles_required() const { | 420 int EchoCancellationImpl::num_handles_required() const { |
382 return apm_->num_output_channels() * | 421 return apm_->num_output_channels() * |
383 apm_->num_reverse_channels(); | 422 apm_->num_reverse_channels(); |
384 } | 423 } |
385 | 424 |
386 int EchoCancellationImpl::GetHandleError(void* handle) const { | 425 int EchoCancellationImpl::GetHandleError(void* handle) const { |
387 assert(handle != NULL); | 426 assert(handle != NULL); |
388 return AudioProcessing::kUnspecifiedError; | 427 return AudioProcessing::kUnspecifiedError; |
389 } | 428 } |
429 | |
430 bool EchoCancellationImpl::RenderQueueItemVerifier( | |
431 const std::vector<float>& v) { | |
432 return ((v.size() == kMinNumSamplesPerFrameToBuffer) || | |
433 (v.size() == kMaxNumSamplesPerFrameToBuffer)); | |
kwiberg-webrtc
2015/10/17 07:50:07
From the names of these constants, I would've expe
peah-webrtc
2015/10/26 09:03:48
I totally agree.
Regarding the names I renamed th
| |
434 } | |
435 | |
390 } // namespace webrtc | 436 } // namespace webrtc |
OLD | NEW |