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

Side by Side Diff: webrtc/modules/audio_processing/aec3/suppression_gain.cc

Issue 2886733002: Transparency increasing tuning for AEC3 (Closed)
Patch Set: Fixed memory issue Created 3 years, 7 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
OLDNEW
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/suppression_gain.h" 11 #include "webrtc/modules/audio_processing/aec3/suppression_gain.h"
12 12
13 #include "webrtc/typedefs.h" 13 #include "webrtc/typedefs.h"
14 #if defined(WEBRTC_ARCH_X86_FAMILY) 14 #if defined(WEBRTC_ARCH_X86_FAMILY)
15 #include <emmintrin.h> 15 #include <emmintrin.h>
16 #endif 16 #endif
17 #include <math.h> 17 #include <math.h>
18 #include <algorithm> 18 #include <algorithm>
19 #include <functional> 19 #include <functional>
20 #include <numeric> 20 #include <numeric>
21 21
22 #include "webrtc/base/checks.h" 22 #include "webrtc/base/checks.h"
23 #include "webrtc/modules/audio_processing/aec3/vector_math.h" 23 #include "webrtc/modules/audio_processing/aec3/vector_math.h"
24 24
25 namespace webrtc { 25 namespace webrtc {
26 namespace { 26 namespace {
27 27
28 void GainPostProcessing(std::array<float, kFftLengthBy2Plus1>* gain_squared) { 28 // Adjust the gains according to the presence of known external filters.
29 void AdjustForExternalFilters(std::array<float, kFftLengthBy2Plus1>* gain) {
29 // Limit the low frequency gains to avoid the impact of the high-pass filter 30 // Limit the low frequency gains to avoid the impact of the high-pass filter
30 // on the lower-frequency gain influencing the overall achieved gain. 31 // on the lower-frequency gain influencing the overall achieved gain.
31 (*gain_squared)[1] = std::min((*gain_squared)[1], (*gain_squared)[2]); 32 (*gain)[0] = (*gain)[1] = std::min((*gain)[1], (*gain)[2]);
32 (*gain_squared)[0] = (*gain_squared)[1];
33 33
34 // Limit the high frequency gains to avoid the impact of the anti-aliasing 34 // Limit the high frequency gains to avoid the impact of the anti-aliasing
35 // filter on the upper-frequency gains influencing the overall achieved 35 // filter on the upper-frequency gains influencing the overall achieved
36 // gain. TODO(peah): Update this when new anti-aliasing filters are 36 // gain. TODO(peah): Update this when new anti-aliasing filters are
37 // implemented. 37 // implemented.
38 constexpr size_t kAntiAliasingImpactLimit = (64 * 2000) / 8000; 38 constexpr size_t kAntiAliasingImpactLimit = (64 * 2000) / 8000;
39 std::for_each(gain_squared->begin() + kAntiAliasingImpactLimit, 39 const float min_upper_gain = (*gain)[kAntiAliasingImpactLimit];
40 gain_squared->end() - 1, 40 std::for_each(
41 [gain_squared, kAntiAliasingImpactLimit](float& a) { 41 gain->begin() + kAntiAliasingImpactLimit, gain->end() - 1,
42 a = std::min(a, (*gain_squared)[kAntiAliasingImpactLimit]); 42 [min_upper_gain](float& a) { a = std::min(a, min_upper_gain); });
43 }); 43 (*gain)[kFftLengthBy2] = (*gain)[kFftLengthBy2Minus1];
44 (*gain_squared)[kFftLengthBy2] = (*gain_squared)[kFftLengthBy2Minus1]; 44 }
45 } 45
46 46 // Computes the gain to apply for the bands beyond the first band.
47 constexpr int kNumIterations = 2; 47 float UpperBandsGain(
48 constexpr float kEchoMaskingMargin = 1.f / 20.f; 48 bool saturated_echo,
49 constexpr float kBandMaskingFactor = 1.f / 10.f; 49 const std::vector<std::vector<float>>& render,
50 constexpr float kTimeMaskingFactor = 1.f / 10.f; 50 const std::array<float, kFftLengthBy2Plus1>& low_band_gain) {
51 51 RTC_DCHECK_LT(0, render.size());
52 // TODO(peah): Add further optimizations, in particular for the divisions.
53 void ComputeGains(
54 Aec3Optimization optimization,
55 const std::array<float, kFftLengthBy2Plus1>& nearend_power,
56 const std::array<float, kFftLengthBy2Plus1>& residual_echo_power,
57 const std::array<float, kFftLengthBy2Plus1>& comfort_noise_power,
58 float strong_nearend_margin,
59 std::array<float, kFftLengthBy2Minus1>* previous_gain_squared,
60 std::array<float, kFftLengthBy2Minus1>* previous_masker,
61 std::array<float, kFftLengthBy2Plus1>* gain) {
62 std::array<float, kFftLengthBy2Minus1> masker;
63 std::array<float, kFftLengthBy2Minus1> same_band_masker;
64 std::array<float, kFftLengthBy2Minus1> one_by_residual_echo_power;
65 std::array<bool, kFftLengthBy2Minus1> strong_nearend;
66 std::array<float, kFftLengthBy2Plus1> neighboring_bands_masker;
67 std::array<float, kFftLengthBy2Plus1>* gain_squared = gain;
68 aec3::VectorMath math(optimization);
69
70 // Precompute 1/residual_echo_power.
71 std::transform(residual_echo_power.begin() + 1, residual_echo_power.end() - 1,
72 one_by_residual_echo_power.begin(),
73 [](float a) { return a > 0.f ? 1.f / a : -1.f; });
74
75 // Precompute indicators for bands with strong nearend.
76 std::transform(
77 residual_echo_power.begin() + 1, residual_echo_power.end() - 1,
78 nearend_power.begin() + 1, strong_nearend.begin(),
79 [&](float a, float b) { return a <= strong_nearend_margin * b; });
80
81 // Precompute masker for the same band.
82 std::transform(comfort_noise_power.begin() + 1, comfort_noise_power.end() - 1,
83 previous_masker->begin(), same_band_masker.begin(),
84 [&](float a, float b) { return a + kTimeMaskingFactor * b; });
85
86 for (int k = 0; k < kNumIterations; ++k) {
87 if (k == 0) {
88 // Add masker from the same band.
89 std::copy(same_band_masker.begin(), same_band_masker.end(),
90 masker.begin());
91 } else {
92 // Add masker for neighboring bands.
93 math.Multiply(nearend_power, *gain_squared, neighboring_bands_masker);
94 math.Accumulate(comfort_noise_power, neighboring_bands_masker);
95 std::transform(
96 neighboring_bands_masker.begin(), neighboring_bands_masker.end() - 2,
97 neighboring_bands_masker.begin() + 2, masker.begin(),
98 [&](float a, float b) { return kBandMaskingFactor * (a + b); });
99
100 // Add masker from the same band.
101 math.Accumulate(same_band_masker, masker);
102 }
103
104 // Compute new gain as:
105 // G2(t,f) = (comfort_noise_power(t,f) + G2(t-1)*nearend_power(t-1)) *
106 // kTimeMaskingFactor
107 // * kEchoMaskingMargin / residual_echo_power(t,f).
108 // or
109 // G2(t,f) = ((comfort_noise_power(t,f) + G2(t-1) *
110 // nearend_power(t-1)) * kTimeMaskingFactor +
111 // (comfort_noise_power(t, f-1) + comfort_noise_power(t, f+1) +
112 // (G2(t,f-1)*nearend_power(t, f-1) +
113 // G2(t,f+1)*nearend_power(t, f+1)) *
114 // kTimeMaskingFactor) * kBandMaskingFactor)
115 // * kEchoMaskingMargin / residual_echo_power(t,f).
116 std::transform(
117 masker.begin(), masker.end(), one_by_residual_echo_power.begin(),
118 gain_squared->begin() + 1, [&](float a, float b) {
119 return b >= 0 ? std::min(kEchoMaskingMargin * a * b, 1.f) : 1.f;
120 });
121
122 // Limit gain for bands with strong nearend.
123 std::transform(gain_squared->begin() + 1, gain_squared->end() - 1,
124 strong_nearend.begin(), gain_squared->begin() + 1,
125 [](float a, bool b) { return b ? 1.f : a; });
126
127 // Limit the allowed gain update over time.
128 std::transform(gain_squared->begin() + 1, gain_squared->end() - 1,
129 previous_gain_squared->begin(), gain_squared->begin() + 1,
130 [](float a, float b) {
131 return b < 0.001f ? std::min(a, 0.001f)
132 : std::min(a, b * 2.f);
133 });
134
135 // Process the gains to avoid artefacts caused by gain realization in the
136 // filterbank and impact of external pre-processing of the signal.
137 GainPostProcessing(gain_squared);
138 }
139
140 std::copy(gain_squared->begin() + 1, gain_squared->end() - 1,
141 previous_gain_squared->begin());
142
143 math.Multiply(
144 rtc::ArrayView<const float>(&(*gain_squared)[1], previous_masker->size()),
145 rtc::ArrayView<const float>(&nearend_power[1], previous_masker->size()),
146 *previous_masker);
147 math.Accumulate(rtc::ArrayView<const float>(&comfort_noise_power[1],
148 previous_masker->size()),
149 *previous_masker);
150 math.Sqrt(*gain);
151 }
152
153 } // namespace
154
155 // Computes an upper bound on the gain to apply for high frequencies.
156 float HighFrequencyGainBound(bool saturated_echo,
157 const std::vector<std::vector<float>>& render) {
158 if (render.size() == 1) { 52 if (render.size() == 1) {
159 return 1.f; 53 return 1.f;
160 } 54 }
161 55
56 constexpr size_t kLowBandGainLimit = kFftLengthBy2 / 2;
57 const float gain_below_8_khz = *std::min_element(
58 low_band_gain.begin() + kLowBandGainLimit, low_band_gain.end());
59
162 // Always attenuate the upper bands when there is saturated echo. 60 // Always attenuate the upper bands when there is saturated echo.
163 if (saturated_echo) { 61 if (saturated_echo) {
164 return 0.001f; 62 return std::min(0.001f, gain_below_8_khz);
165 } 63 }
166 64
167 // Compute the upper and lower band energies. 65 // Compute the upper and lower band energies.
168 float low_band_energy = 66 const auto sum_of_squares = [](float a, float b) { return a + b * b; };
169 std::accumulate(render[0].begin(), render[0].end(), 0.f, 67 const float low_band_energy =
170 [](float a, float b) -> float { return a + b * b; }); 68 std::accumulate(render[0].begin(), render[0].end(), 0.f, sum_of_squares);
171 float high_band_energies = 0.f; 69 float high_band_energy = 0.f;
172 for (size_t k = 1; k < render.size(); ++k) { 70 for (size_t k = 1; k < render.size(); ++k) {
173 high_band_energies = std::max( 71 const float energy = std::accumulate(render[k].begin(), render[k].end(),
174 high_band_energies, 72 0.f, sum_of_squares);
175 std::accumulate(render[k].begin(), render[k].end(), 0.f, 73 high_band_energy = std::max(high_band_energy, energy);
176 [](float a, float b) -> float { return a + b * b; }));
177 } 74 }
178 75
179 // If there is more power in the lower frequencies than the upper frequencies, 76 // If there is more power in the lower frequencies than the upper frequencies,
180 // or if the power in upper frequencies is low, do not bound the gain in the 77 // or if the power in upper frequencies is low, do not bound the gain in the
181 // upper bands. 78 // upper bands.
182 if (high_band_energies < low_band_energy || 79 float anti_howling_gain;
183 high_band_energies < kSubBlockSize * 10.f * 10.f) { 80 constexpr float kThreshold = kSubBlockSize * 10.f * 10.f;
184 return 1.f; 81 if (high_band_energy < std::max(low_band_energy, kThreshold)) {
185 } 82 anti_howling_gain = 1.f;
186 83 } else {
187 // In all other cases, bound the gain for upper frequencies. 84 // In all other cases, bound the gain for upper frequencies.
188 RTC_DCHECK_LE(low_band_energy, high_band_energies); 85 RTC_DCHECK_LE(low_band_energy, high_band_energy);
189 return 0.01f * sqrtf(low_band_energy / high_band_energies); 86 RTC_DCHECK_NE(0.f, high_band_energy);
87 anti_howling_gain = 0.01f * sqrtf(low_band_energy / high_band_energy);
88 }
89
90 // Choose the gain as the minimum of the lower and upper gains.
91 return std::min(gain_below_8_khz, anti_howling_gain);
92 }
93
94 // Limits the gain increase.
95 void UpdateMaxGainIncrease(
96 size_t no_saturation_counter,
97 bool low_noise_render,
98 const std::array<float, kFftLengthBy2Plus1>& last_echo,
99 const std::array<float, kFftLengthBy2Plus1>& echo,
100 const std::array<float, kFftLengthBy2Plus1>& last_gain,
101 const std::array<float, kFftLengthBy2Plus1>& new_gain,
102 std::array<float, kFftLengthBy2Plus1>* gain_increase) {
103 float max_increasing;
104 float max_decreasing;
105 float rate_increasing;
106 float rate_decreasing;
107 float min_increasing;
108 float min_decreasing;
109
110 if (low_noise_render) {
111 max_increasing = 8.f;
112 max_decreasing = 8.f;
113 rate_increasing = 2.f;
114 rate_decreasing = 2.f;
115 min_increasing = 4.f;
116 min_decreasing = 4.f;
117 } else if (no_saturation_counter > 10) {
118 max_increasing = 4.f;
119 max_decreasing = 4.f;
120 rate_increasing = 2.f;
121 rate_decreasing = 2.f;
122 min_increasing = 1.2f;
123 min_decreasing = 2.f;
124 } else {
125 max_increasing = 1.2f;
126 max_decreasing = 1.2f;
127 rate_increasing = 1.5f;
128 rate_decreasing = 1.5f;
129 min_increasing = 1.f;
130 min_decreasing = 1.f;
131 }
132
133 for (size_t k = 0; k < new_gain.size(); ++k) {
134 if (echo[k] > last_echo[k]) {
135 (*gain_increase)[k] =
136 new_gain[k] > last_gain[k]
137 ? std::min(max_increasing, (*gain_increase)[k] * rate_increasing)
138 : min_increasing;
139 } else {
140 (*gain_increase)[k] =
141 new_gain[k] > last_gain[k]
142 ? std::min(max_decreasing, (*gain_increase)[k] * rate_decreasing)
143 : min_decreasing;
144 }
145 }
146 }
147
148 // Computes the gain to reduce the echo to a non audible level.
149 void GainToNoAudibleEcho(
150 bool low_noise_render,
151 bool saturated_echo,
152 const std::array<float, kFftLengthBy2Plus1>& nearend,
153 const std::array<float, kFftLengthBy2Plus1>& echo,
154 const std::array<float, kFftLengthBy2Plus1>& masker,
155 const std::array<float, kFftLengthBy2Plus1>& min_gain,
156 const std::array<float, kFftLengthBy2Plus1>& max_gain,
157 const std::array<float, kFftLengthBy2Plus1>& one_by_echo,
158 std::array<float, kFftLengthBy2Plus1>* gain) {
159 constexpr float kEchoMaskingMargin = 1.f / 100.f;
160 const float nearend_masking_margin =
161 low_noise_render ? 2.f : (saturated_echo ? 0.001f : 0.01f);
162
163 for (size_t k = 0; k < gain->size(); ++k) {
164 RTC_DCHECK_LE(0.f, nearend_masking_margin * nearend[k]);
165 if (echo[k] <= nearend_masking_margin * nearend[k]) {
166 (*gain)[k] = 1.f;
167 } else {
168 (*gain)[k] = kEchoMaskingMargin * masker[k] * one_by_echo[k];
169 }
170
171 (*gain)[k] = std::min(std::max((*gain)[k], min_gain[k]), max_gain[k]);
172 }
173 }
174
175 // Computes the signal output power that masks the echo signal.
176 void MaskingPower(const std::array<float, kFftLengthBy2Plus1>& nearend,
177 const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
178 const std::array<float, kFftLengthBy2Plus1>& last_masker,
179 const std::array<float, kFftLengthBy2Plus1>& gain,
180 std::array<float, kFftLengthBy2Plus1>* masker) {
181 std::array<float, kFftLengthBy2Plus1> side_band_masker;
182 for (size_t k = 0; k < gain.size(); ++k) {
183 side_band_masker[k] = nearend[k] * gain[k] + comfort_noise[k];
184 (*masker)[k] = comfort_noise[k] + 0.1f * last_masker[k];
185 }
186 for (size_t k = 1; k < gain.size() - 1; ++k) {
187 (*masker)[k] += 0.1f * (side_band_masker[k - 1] + side_band_masker[k + 1]);
188 }
189 }
190
191 } // namespace
192
193 // TODO(peah): Add further optimizations, in particular for the divisions.
194 void SuppressionGain::LowerBandGain(
195 bool low_noise_render,
196 bool saturated_echo,
197 const std::array<float, kFftLengthBy2Plus1>& nearend,
198 const std::array<float, kFftLengthBy2Plus1>& echo,
199 const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
200 std::array<float, kFftLengthBy2Plus1>* gain) {
201 // Count the number of blocks since saturation.
202 no_saturation_counter_ = saturated_echo ? 0 : no_saturation_counter_ + 1;
203
204 // Precompute 1/echo (note that when the echo is zero, the precomputed value
205 // is never used).
206 std::array<float, kFftLengthBy2Plus1> one_by_echo;
207 std::transform(echo.begin(), echo.end(), one_by_echo.begin(),
208 [](float a) { return a > 0.f ? 1.f / a : 1.f; });
209
210 // Compute the minimum gain as the attenuating gain to put the signal just
211 // above the zero sample values.
212 std::array<float, kFftLengthBy2Plus1> min_gain;
213 const float min_echo_power = low_noise_render ? 192.f : 64.f;
214 if (no_saturation_counter_ > 10) {
215 for (size_t k = 0; k < nearend.size(); ++k) {
216 const float denom = std::min(nearend[k], echo[k]);
217 min_gain[k] = denom > 0.f ? min_echo_power / denom : 1.f;
218 min_gain[k] = std::min(min_gain[k], 1.f);
219 }
220 } else {
221 min_gain.fill(0.f);
222 }
223
224 // Compute the maximum gain by limiting the gain increase from the previous
225 // gain.
226 std::array<float, kFftLengthBy2Plus1> max_gain;
227 for (size_t k = 0; k < gain->size(); ++k) {
228 max_gain[k] =
229 std::min(std::max(last_gain_[k] * gain_increase_[k], 0.001f), 1.f);
230 }
231
232 // Iteratively compute the gain required to attenuate the echo to a non
233 // noticeable level.
234 gain->fill(0.f);
235 for (int k = 0; k < 2; ++k) {
236 std::array<float, kFftLengthBy2Plus1> masker;
237 MaskingPower(nearend, comfort_noise, last_masker_, *gain, &masker);
238 GainToNoAudibleEcho(low_noise_render, saturated_echo, nearend, echo, masker,
239 min_gain, max_gain, one_by_echo, gain);
240 AdjustForExternalFilters(gain);
241 }
242
243 // Update the allowed maximum gain increase.
244 UpdateMaxGainIncrease(no_saturation_counter_, low_noise_render, last_echo_,
245 echo, last_gain_, *gain, &gain_increase_);
246
247 // Store data required for the gain computation of the next block.
248 std::copy(echo.begin(), echo.end(), last_echo_.begin());
249 std::copy(gain->begin(), gain->end(), last_gain_.begin());
250 MaskingPower(nearend, comfort_noise, last_masker_, *gain, &last_masker_);
251 aec3::VectorMath(optimization_).Sqrt(*gain);
190 } 252 }
191 253
192 SuppressionGain::SuppressionGain(Aec3Optimization optimization) 254 SuppressionGain::SuppressionGain(Aec3Optimization optimization)
193 : optimization_(optimization) { 255 : optimization_(optimization) {
194 previous_gain_squared_.fill(1.f); 256 last_gain_.fill(1.f);
195 previous_masker_.fill(0.f); 257 last_masker_.fill(0.f);
258 gain_increase_.fill(1.f);
259 last_echo_.fill(0.f);
196 } 260 }
197 261
198 void SuppressionGain::GetGain( 262 void SuppressionGain::GetGain(
199 const std::array<float, kFftLengthBy2Plus1>& nearend_power, 263 const std::array<float, kFftLengthBy2Plus1>& nearend,
200 const std::array<float, kFftLengthBy2Plus1>& residual_echo_power, 264 const std::array<float, kFftLengthBy2Plus1>& echo,
201 const std::array<float, kFftLengthBy2Plus1>& comfort_noise_power, 265 const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
202 bool saturated_echo, 266 bool saturated_echo,
203 const std::vector<std::vector<float>>& render, 267 const std::vector<std::vector<float>>& render,
204 size_t num_capture_bands,
205 bool force_zero_gain, 268 bool force_zero_gain,
206 float* high_bands_gain, 269 float* high_bands_gain,
207 std::array<float, kFftLengthBy2Plus1>* low_band_gain) { 270 std::array<float, kFftLengthBy2Plus1>* low_band_gain) {
208 RTC_DCHECK(high_bands_gain); 271 RTC_DCHECK(high_bands_gain);
209 RTC_DCHECK(low_band_gain); 272 RTC_DCHECK(low_band_gain);
210 273
211 if (force_zero_gain) { 274 if (force_zero_gain) {
212 previous_gain_squared_.fill(0.f); 275 last_gain_.fill(0.f);
213 std::copy(comfort_noise_power.begin() + 1, comfort_noise_power.end() - 1, 276 std::copy(comfort_noise.begin(), comfort_noise.end(), last_masker_.begin());
214 previous_masker_.begin());
215 low_band_gain->fill(0.f); 277 low_band_gain->fill(0.f);
278 gain_increase_.fill(1.f);
216 *high_bands_gain = 0.f; 279 *high_bands_gain = 0.f;
217 return; 280 return;
218 } 281 }
219 282
220 // Choose margin to use. 283 bool low_noise_render = low_render_detector_.Detect(render);
221 const float margin = saturated_echo ? 0.001f : 0.01f;
222 ComputeGains(optimization_, nearend_power, residual_echo_power,
223 comfort_noise_power, margin, &previous_gain_squared_,
224 &previous_masker_, low_band_gain);
225 284
226 if (num_capture_bands > 1) { 285 // Compute gain for the lower band.
227 // Compute the gain for upper frequencies. 286 LowerBandGain(low_noise_render, saturated_echo, nearend, echo, comfort_noise,
228 const float min_high_band_gain = 287 low_band_gain);
229 HighFrequencyGainBound(saturated_echo, render);
230 *high_bands_gain =
231 *std::min_element(low_band_gain->begin() + 32, low_band_gain->end());
232 288
233 *high_bands_gain = std::min(*high_bands_gain, min_high_band_gain); 289 // Compute the gain for the upper bands.
290 *high_bands_gain = UpperBandsGain(saturated_echo, render, *low_band_gain);
291 }
234 292
235 } else { 293 // Detects when the render signal can be considered to have low power and
236 *high_bands_gain = 1.f; 294 // consist of stationary noise.
295 bool SuppressionGain::LowNoiseRenderDetector::Detect(
296 const std::vector<std::vector<float>>& render) {
297 float x2_sum = 0.f;
298 float x2_max = 0.f;
299 for (auto x_k : render[0]) {
300 const float x2 = x_k * x_k;
301 x2_sum += x2;
302 x2_max = std::max(x2_max, x2);
237 } 303 }
304
305 constexpr float kThreshold = 50.f * 50.f * 64.f;
306 const bool low_noise_render =
307 average_power_ < kThreshold && x2_max < 3 * average_power_;
308 average_power_ = average_power_ * 0.9f + x2_sum * 0.1f;
309 return low_noise_render;
238 } 310 }
239 311
240 } // namespace webrtc 312 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698