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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 erl_estimator_.Update(X2, Y2); | 147 erl_estimator_.Update(X2, Y2); |
151 } | 148 } |
152 | 149 |
153 // Detect and flag echo saturation. | 150 // Detect and flag echo saturation. |
154 // TODO(peah): Add the delay in this computation to ensure that the render and | 151 // TODO(peah): Add the delay in this computation to ensure that the render and |
155 // capture signals are properly aligned. | 152 // capture signals are properly aligned. |
156 RTC_DCHECK_LT(0, x.size()); | 153 RTC_DCHECK_LT(0, x.size()); |
157 const float max_sample = fabs(*std::max_element( | 154 const float max_sample = fabs(*std::max_element( |
158 x.begin(), x.end(), [](float a, float b) { return a * a < b * b; })); | 155 x.begin(), x.end(), [](float a, float b) { return a * a < b * b; })); |
159 const bool saturated_echo = | 156 const bool saturated_echo = |
160 previous_max_sample_ * kFixedEchoPathGain > 1600 && SaturatedCapture(); | 157 previous_max_sample_ * 100 > 1600 && SaturatedCapture(); |
161 previous_max_sample_ = max_sample; | 158 previous_max_sample_ = max_sample; |
162 | 159 |
163 // Counts the blocks since saturation. | 160 // Counts the blocks since saturation. |
| 161 constexpr size_t kSaturationLeakageBlocks = 20; |
164 blocks_since_last_saturation_ = | 162 blocks_since_last_saturation_ = |
165 saturated_echo ? 0 : blocks_since_last_saturation_ + 1; | 163 saturated_echo ? 0 : blocks_since_last_saturation_ + 1; |
166 echo_saturation_ = blocks_since_last_saturation_ < kSaturationLeakageBlocks; | 164 echo_saturation_ = blocks_since_last_saturation_ < kSaturationLeakageBlocks; |
167 | 165 |
168 // Flag whether the linear filter estimate is usable. | 166 // Flag whether the linear filter estimate is usable. |
| 167 constexpr size_t kEchoPathChangeConvergenceBlocks = 2 * kNumBlocksPerSecond; |
169 usable_linear_estimate_ = | 168 usable_linear_estimate_ = |
170 (!echo_saturation_) && | 169 (!echo_saturation_) && |
171 (!render_received_ || | 170 (!render_received_ || |
172 blocks_with_filter_adaptation_ > kEchoPathChangeConvergenceBlocks) && | 171 blocks_with_filter_adaptation_ > kEchoPathChangeConvergenceBlocks) && |
173 filter_delay_ && echo_path_change_counter_ <= 0; | 172 filter_delay_ && echo_path_change_counter_ <= 0; |
174 | 173 |
175 // After an amount of active render samples for which an echo should have been | 174 // After an amount of active render samples for which an echo should have been |
176 // detected in the capture signal if the ERL was not infinite, flag that a | 175 // detected in the capture signal if the ERL was not infinite, flag that a |
177 // headset is used. | 176 // headset is used. |
178 headset_detected_ = | 177 constexpr size_t kHeadSetDetectionBlocks = 5 * kNumBlocksPerSecond; |
179 !external_delay_ && !filter_delay_ && | 178 headset_detected_ = !external_delay_ && !filter_delay_ && |
180 (!render_received_ || | 179 (!render_received_ || blocks_with_filter_adaptation_ >= |
181 blocks_with_filter_adaptation_ >= kEchoPathChangeConvergenceBlocks); | 180 kHeadSetDetectionBlocks); |
182 } | 181 } |
183 | 182 |
184 } // namespace webrtc | 183 } // namespace webrtc |
OLD | NEW |