OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 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/aec3/aec_state.h" | 11 #include "webrtc/modules/audio_processing/aec3/aec_state.h" |
12 | 12 |
13 #include <math.h> | 13 #include <math.h> |
14 #include <numeric> | 14 #include <numeric> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" | 17 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" |
18 #include "webrtc/rtc_base/array_view.h" | 18 #include "webrtc/rtc_base/array_view.h" |
19 #include "webrtc/rtc_base/atomicops.h" | 19 #include "webrtc/rtc_base/atomicops.h" |
20 #include "webrtc/rtc_base/checks.h" | 20 #include "webrtc/rtc_base/checks.h" |
21 | 21 |
22 namespace webrtc { | 22 namespace webrtc { |
23 namespace { | 23 namespace { |
24 | 24 |
25 constexpr size_t kEchoPathChangeConvergenceBlocks = 2 * kNumBlocksPerSecond; | |
26 constexpr size_t kSaturationLeakageBlocks = 20; | |
27 | |
28 // Computes delay of the adaptive filter. | 25 // Computes delay of the adaptive filter. |
29 rtc::Optional<size_t> EstimateFilterDelay( | 26 rtc::Optional<size_t> EstimateFilterDelay( |
30 const std::vector<std::array<float, kFftLengthBy2Plus1>>& | 27 const std::vector<std::array<float, kFftLengthBy2Plus1>>& |
31 adaptive_filter_frequency_response) { | 28 adaptive_filter_frequency_response) { |
32 const auto& H2 = adaptive_filter_frequency_response; | 29 const auto& H2 = adaptive_filter_frequency_response; |
33 | 30 |
34 size_t reliable_delays_sum = 0; | 31 size_t reliable_delays_sum = 0; |
35 size_t num_reliable_delays = 0; | 32 size_t num_reliable_delays = 0; |
36 | 33 |
37 constexpr size_t kUpperBin = kFftLengthBy2 - 5; | 34 constexpr size_t kUpperBin = kFftLengthBy2 - 5; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 erl_estimator_.Update(X2, Y2); | 153 erl_estimator_.Update(X2, Y2); |
157 } | 154 } |
158 | 155 |
159 // Detect and flag echo saturation. | 156 // Detect and flag echo saturation. |
160 // TODO(peah): Add the delay in this computation to ensure that the render and | 157 // TODO(peah): Add the delay in this computation to ensure that the render and |
161 // capture signals are properly aligned. | 158 // capture signals are properly aligned. |
162 RTC_DCHECK_LT(0, x.size()); | 159 RTC_DCHECK_LT(0, x.size()); |
163 const float max_sample = fabs(*std::max_element( | 160 const float max_sample = fabs(*std::max_element( |
164 x.begin(), x.end(), [](float a, float b) { return a * a < b * b; })); | 161 x.begin(), x.end(), [](float a, float b) { return a * a < b * b; })); |
165 const bool saturated_echo = | 162 const bool saturated_echo = |
166 previous_max_sample_ * kFixedEchoPathGain > 1600 && SaturatedCapture(); | 163 previous_max_sample_ * 100 > 1600 && SaturatedCapture(); |
167 previous_max_sample_ = max_sample; | 164 previous_max_sample_ = max_sample; |
168 | 165 |
169 // Counts the blocks since saturation. | 166 // Counts the blocks since saturation. |
| 167 constexpr size_t kSaturationLeakageBlocks = 20; |
170 blocks_since_last_saturation_ = | 168 blocks_since_last_saturation_ = |
171 saturated_echo ? 0 : blocks_since_last_saturation_ + 1; | 169 saturated_echo ? 0 : blocks_since_last_saturation_ + 1; |
172 echo_saturation_ = blocks_since_last_saturation_ < kSaturationLeakageBlocks; | 170 echo_saturation_ = blocks_since_last_saturation_ < kSaturationLeakageBlocks; |
173 | 171 |
174 // Flag whether the linear filter estimate is usable. | 172 // Flag whether the linear filter estimate is usable. |
| 173 constexpr size_t kEchoPathChangeConvergenceBlocks = 2 * kNumBlocksPerSecond; |
175 usable_linear_estimate_ = | 174 usable_linear_estimate_ = |
176 (!echo_saturation_) && | 175 (!echo_saturation_) && |
177 (!render_received_ || | 176 (!render_received_ || |
178 blocks_with_filter_adaptation_ > kEchoPathChangeConvergenceBlocks) && | 177 blocks_with_filter_adaptation_ > kEchoPathChangeConvergenceBlocks) && |
179 filter_delay_ && echo_path_change_counter_ <= 0; | 178 filter_delay_ && echo_path_change_counter_ <= 0; |
180 | 179 |
181 // After an amount of active render samples for which an echo should have been | 180 // After an amount of active render samples for which an echo should have been |
182 // detected in the capture signal if the ERL was not infinite, flag that a | 181 // detected in the capture signal if the ERL was not infinite, flag that a |
183 // headset is used. | 182 // headset is used. |
184 headset_detected_ = | 183 constexpr size_t kHeadSetDetectionBlocks = 5 * kNumBlocksPerSecond; |
185 !external_delay_ && !filter_delay_ && | 184 headset_detected_ = !external_delay_ && !filter_delay_ && |
186 (!render_received_ || | 185 (!render_received_ || blocks_with_filter_adaptation_ >= |
187 blocks_with_filter_adaptation_ >= kEchoPathChangeConvergenceBlocks); | 186 kHeadSetDetectionBlocks); |
188 | 187 |
189 // Update the room reverb estimate. | 188 // Update the room reverb estimate. |
190 UpdateReverb(adaptive_filter_impulse_response); | 189 UpdateReverb(adaptive_filter_impulse_response); |
191 } | 190 } |
192 | 191 |
193 void AecState::UpdateReverb( | 192 void AecState::UpdateReverb( |
194 const std::array<float, kAdaptiveFilterTimeDomainLength>& | 193 const std::array<float, kAdaptiveFilterTimeDomainLength>& |
195 impulse_response) { | 194 impulse_response) { |
196 if ((!(filter_delay_ && usable_linear_estimate_)) || | 195 if ((!(filter_delay_ && usable_linear_estimate_)) || |
197 (*filter_delay_ > kAdaptiveFilterLength - 4)) { | 196 (*filter_delay_ > kAdaptiveFilterLength - 4)) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 max_nearend_ = e_abs; | 300 max_nearend_ = e_abs; |
302 max_nearend_counter_ = 0; | 301 max_nearend_counter_ = 0; |
303 } else { | 302 } else { |
304 if (++max_nearend_counter_ > 5 * kNumBlocksPerSecond) { | 303 if (++max_nearend_counter_ > 5 * kNumBlocksPerSecond) { |
305 max_nearend_ *= 0.995f; | 304 max_nearend_ *= 0.995f; |
306 } | 305 } |
307 } | 306 } |
308 } | 307 } |
309 | 308 |
310 } // namespace webrtc | 309 } // namespace webrtc |
OLD | NEW |