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 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 EchoGeneratingPower(render_buffer, 0, | 129 EchoGeneratingPower(render_buffer, 0, |
130 kResidualEchoPowerRenderWindowSize - 1, &X2); | 130 kResidualEchoPowerRenderWindowSize - 1, &X2); |
131 } | 131 } |
132 | 132 |
133 // Subtract the stationary noise power to avoid stationary noise causing | 133 // Subtract the stationary noise power to avoid stationary noise causing |
134 // excessive echo suppression. | 134 // excessive echo suppression. |
135 std::transform( | 135 std::transform( |
136 X2.begin(), X2.end(), X2_noise_floor_.begin(), X2.begin(), | 136 X2.begin(), X2.end(), X2_noise_floor_.begin(), X2.begin(), |
137 [](float a, float b) { return std::max(0.f, a - 10.f * b); }); | 137 [](float a, float b) { return std::max(0.f, a - 10.f * b); }); |
138 | 138 |
139 NonLinearEstimate( | 139 NonLinearEstimate(aec_state.HeadsetDetected(), X2, Y2, R2); |
140 aec_state.HeadsetDetected() ? kHeadsetEchoPathGain : kFixedEchoPathGain, | |
141 X2, Y2, R2); | |
142 AddEchoReverb(*R2, aec_state.SaturatedEcho(), | 140 AddEchoReverb(*R2, aec_state.SaturatedEcho(), |
143 std::min(static_cast<size_t>(kAdaptiveFilterLength), | 141 std::min(static_cast<size_t>(kAdaptiveFilterLength), |
144 delay.value_or(kAdaptiveFilterLength)), | 142 delay.value_or(kAdaptiveFilterLength)), |
145 aec_state.ReverbDecay(), R2); | 143 aec_state.ReverbDecay(), R2); |
146 } | 144 } |
147 | 145 |
148 // If the echo is deemed inaudible, set the residual echo to zero. | 146 // If the echo is deemed inaudible, set the residual echo to zero. |
149 if (aec_state.InaudibleEcho()) { | 147 if (aec_state.InaudibleEcho()) { |
150 R2->fill(0.f); | 148 R2->fill(0.f); |
151 } | 149 } |
(...skipping 25 matching lines...) Expand all Loading... |
177 std::array<float, kFftLengthBy2Plus1>* R2) { | 175 std::array<float, kFftLengthBy2Plus1>* R2) { |
178 std::fill(R2_hold_counter_.begin(), R2_hold_counter_.end(), 10.f); | 176 std::fill(R2_hold_counter_.begin(), R2_hold_counter_.end(), 10.f); |
179 std::transform(erle.begin(), erle.end(), S2_linear.begin(), R2->begin(), | 177 std::transform(erle.begin(), erle.end(), S2_linear.begin(), R2->begin(), |
180 [](float a, float b) { | 178 [](float a, float b) { |
181 RTC_DCHECK_LT(0.f, a); | 179 RTC_DCHECK_LT(0.f, a); |
182 return b / a; | 180 return b / a; |
183 }); | 181 }); |
184 } | 182 } |
185 | 183 |
186 void ResidualEchoEstimator::NonLinearEstimate( | 184 void ResidualEchoEstimator::NonLinearEstimate( |
187 float echo_path_gain, | 185 bool headset_detected, |
188 const std::array<float, kFftLengthBy2Plus1>& X2, | 186 const std::array<float, kFftLengthBy2Plus1>& X2, |
189 const std::array<float, kFftLengthBy2Plus1>& Y2, | 187 const std::array<float, kFftLengthBy2Plus1>& Y2, |
190 std::array<float, kFftLengthBy2Plus1>* R2) { | 188 std::array<float, kFftLengthBy2Plus1>* R2) { |
| 189 // Choose gains. |
| 190 const float echo_path_gain_lf = headset_detected ? kHeadsetEchoPathGain : 100; |
| 191 const float echo_path_gain_mf = |
| 192 headset_detected ? kHeadsetEchoPathGain : 1000; |
| 193 const float echo_path_gain_hf = |
| 194 headset_detected ? kHeadsetEchoPathGain : 5000; |
| 195 |
191 // Compute preliminary residual echo. | 196 // Compute preliminary residual echo. |
192 std::transform(X2.begin(), X2.end(), R2->begin(), | 197 std::transform( |
193 [echo_path_gain](float a) { return a * echo_path_gain; }); | 198 X2.begin(), X2.begin() + 12, R2->begin(), |
| 199 [echo_path_gain_lf](float a) { return a * echo_path_gain_lf; }); |
| 200 std::transform( |
| 201 X2.begin() + 12, X2.begin() + 25, R2->begin() + 12, |
| 202 [echo_path_gain_mf](float a) { return a * echo_path_gain_mf; }); |
| 203 std::transform( |
| 204 X2.begin() + 25, X2.end(), R2->begin() + 25, |
| 205 [echo_path_gain_hf](float a) { return a * echo_path_gain_hf; }); |
194 | 206 |
195 for (size_t k = 0; k < R2->size(); ++k) { | 207 for (size_t k = 0; k < R2->size(); ++k) { |
196 // Update hold counter. | 208 // Update hold counter. |
197 R2_hold_counter_[k] = R2_old_[k] < (*R2)[k] ? 0 : R2_hold_counter_[k] + 1; | 209 R2_hold_counter_[k] = R2_old_[k] < (*R2)[k] ? 0 : R2_hold_counter_[k] + 1; |
198 | 210 |
199 // Compute the residual echo by holding a maximum echo powers and an echo | 211 // Compute the residual echo by holding a maximum echo powers and an echo |
200 // fading corresponding to a room with an RT60 value of about 50 ms. | 212 // fading corresponding to a room with an RT60 value of about 50 ms. |
201 (*R2)[k] = R2_hold_counter_[k] < 2 | 213 (*R2)[k] = R2_hold_counter_[k] < 2 |
202 ? std::max((*R2)[k], R2_old_[k]) | 214 ? std::max((*R2)[k], R2_old_[k]) |
203 : std::min((*R2)[k] + R2_old_[k] * 0.1f, Y2[k]); | 215 : std::min((*R2)[k] + R2_old_[k] * 0.1f, Y2[k]); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 } else { | 251 } else { |
240 std::copy(S2.begin(), S2.end(), S2_old_[S2_old_index_].begin()); | 252 std::copy(S2.begin(), S2.end(), S2_old_[S2_old_index_].begin()); |
241 } | 253 } |
242 | 254 |
243 // Add the power of the echo reverb to the residual echo power. | 255 // Add the power of the echo reverb to the residual echo power. |
244 std::transform(R2->begin(), R2->end(), R2_reverb_.begin(), R2->begin(), | 256 std::transform(R2->begin(), R2->end(), R2_reverb_.begin(), R2->begin(), |
245 std::plus<float>()); | 257 std::plus<float>()); |
246 } | 258 } |
247 | 259 |
248 } // namespace webrtc | 260 } // namespace webrtc |
OLD | NEW |