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

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

Issue 3003733002: Utilizing the AEC3 config struct for constants. (Closed)
Patch Set: Added copy assignment Created 3 years, 3 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
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 RTC_DCHECK_NE(0.f, high_band_energy); 102 RTC_DCHECK_NE(0.f, high_band_energy);
103 anti_howling_gain = 0.01f * sqrtf(low_band_energy / high_band_energy); 103 anti_howling_gain = 0.01f * sqrtf(low_band_energy / high_band_energy);
104 } 104 }
105 105
106 // Choose the gain as the minimum of the lower and upper gains. 106 // Choose the gain as the minimum of the lower and upper gains.
107 return std::min(gain_below_8_khz, anti_howling_gain); 107 return std::min(gain_below_8_khz, anti_howling_gain);
108 } 108 }
109 109
110 // Limits the gain increase. 110 // Limits the gain increase.
111 void UpdateMaxGainIncrease( 111 void UpdateMaxGainIncrease(
112 const AudioProcessing::Config::EchoCanceller3& config,
112 size_t no_saturation_counter, 113 size_t no_saturation_counter,
113 bool low_noise_render, 114 bool low_noise_render,
114 const std::array<float, kFftLengthBy2Plus1>& last_echo, 115 const std::array<float, kFftLengthBy2Plus1>& last_echo,
115 const std::array<float, kFftLengthBy2Plus1>& echo, 116 const std::array<float, kFftLengthBy2Plus1>& echo,
116 const std::array<float, kFftLengthBy2Plus1>& last_gain, 117 const std::array<float, kFftLengthBy2Plus1>& last_gain,
117 const std::array<float, kFftLengthBy2Plus1>& new_gain, 118 const std::array<float, kFftLengthBy2Plus1>& new_gain,
118 std::array<float, kFftLengthBy2Plus1>* gain_increase) { 119 std::array<float, kFftLengthBy2Plus1>* gain_increase) {
119 float max_increasing; 120 float max_increasing;
120 float max_decreasing; 121 float max_decreasing;
121 float rate_increasing; 122 float rate_increasing;
122 float rate_decreasing; 123 float rate_decreasing;
123 float min_increasing; 124 float min_increasing;
124 float min_decreasing; 125 float min_decreasing;
125 126
127 auto& param = config.param.gain_updates;
126 if (low_noise_render) { 128 if (low_noise_render) {
127 max_increasing = 8.f; 129 max_increasing = param.low_noise.max_inc;
128 max_decreasing = 8.f; 130 max_decreasing = param.low_noise.max_dec;
129 rate_increasing = 2.f; 131 rate_increasing = param.low_noise.rate_inc;
130 rate_decreasing = 2.f; 132 rate_decreasing = param.low_noise.rate_dec;
131 min_increasing = 4.f; 133 min_increasing = param.low_noise.min_inc;
132 min_decreasing = 4.f; 134 min_decreasing = param.low_noise.min_dec;
133 } else if (no_saturation_counter > 10) { 135 } else if (no_saturation_counter > 10) {
134 max_increasing = 4.f; 136 max_increasing = param.normal.max_inc;
135 max_decreasing = 4.f; 137 max_decreasing = param.normal.max_dec;
136 rate_increasing = 2.f; 138 rate_increasing = param.normal.rate_inc;
137 rate_decreasing = 2.f; 139 rate_decreasing = param.normal.rate_dec;
138 min_increasing = 1.2f; 140 min_increasing = param.normal.min_inc;
139 min_decreasing = 2.f; 141 min_decreasing = param.normal.min_dec;
140 } else { 142 } else {
141 max_increasing = 1.2f; 143 max_increasing = param.saturation.max_inc;
142 max_decreasing = 1.2f; 144 max_decreasing = param.saturation.max_dec;
143 rate_increasing = 1.5f; 145 rate_increasing = param.saturation.rate_inc;
144 rate_decreasing = 1.5f; 146 rate_decreasing = param.saturation.rate_dec;
145 min_increasing = 1.f; 147 min_increasing = param.saturation.min_inc;
146 min_decreasing = 1.f; 148 min_decreasing = param.saturation.min_dec;
147 } 149 }
148 150
149 for (size_t k = 0; k < new_gain.size(); ++k) { 151 for (size_t k = 0; k < new_gain.size(); ++k) {
150 if (echo[k] > last_echo[k]) { 152 if (echo[k] > last_echo[k]) {
151 (*gain_increase)[k] = 153 (*gain_increase)[k] =
152 new_gain[k] > last_gain[k] 154 new_gain[k] > last_gain[k]
153 ? std::min(max_increasing, (*gain_increase)[k] * rate_increasing) 155 ? std::min(max_increasing, (*gain_increase)[k] * rate_increasing)
154 : min_increasing; 156 : min_increasing;
155 } else { 157 } else {
156 (*gain_increase)[k] = 158 (*gain_increase)[k] =
157 new_gain[k] > last_gain[k] 159 new_gain[k] > last_gain[k]
158 ? std::min(max_decreasing, (*gain_increase)[k] * rate_decreasing) 160 ? std::min(max_decreasing, (*gain_increase)[k] * rate_decreasing)
159 : min_decreasing; 161 : min_decreasing;
160 } 162 }
161 } 163 }
162 } 164 }
163 165
164 // Computes the gain to reduce the echo to a non audible level. 166 // Computes the gain to reduce the echo to a non audible level.
165 void GainToNoAudibleEcho( 167 void GainToNoAudibleEcho(
168 const AudioProcessing::Config::EchoCanceller3& config,
166 bool low_noise_render, 169 bool low_noise_render,
167 bool saturated_echo, 170 bool saturated_echo,
168 const std::array<float, kFftLengthBy2Plus1>& nearend, 171 const std::array<float, kFftLengthBy2Plus1>& nearend,
169 const std::array<float, kFftLengthBy2Plus1>& echo, 172 const std::array<float, kFftLengthBy2Plus1>& echo,
170 const std::array<float, kFftLengthBy2Plus1>& masker, 173 const std::array<float, kFftLengthBy2Plus1>& masker,
171 const std::array<float, kFftLengthBy2Plus1>& min_gain, 174 const std::array<float, kFftLengthBy2Plus1>& min_gain,
172 const std::array<float, kFftLengthBy2Plus1>& max_gain, 175 const std::array<float, kFftLengthBy2Plus1>& max_gain,
173 const std::array<float, kFftLengthBy2Plus1>& one_by_echo, 176 const std::array<float, kFftLengthBy2Plus1>& one_by_echo,
174 std::array<float, kFftLengthBy2Plus1>* gain) { 177 std::array<float, kFftLengthBy2Plus1>* gain) {
175 constexpr float kEchoMaskingMargin = 1.f / 100.f;
176 const float nearend_masking_margin = 178 const float nearend_masking_margin =
177 low_noise_render ? 0.1f : (saturated_echo ? 0.001f : 0.01f); 179 low_noise_render ? 0.1f
180 : (saturated_echo ? config.param.gain_mask.m2
181 : config.param.gain_mask.m3);
178 182
179 for (size_t k = 0; k < gain->size(); ++k) { 183 for (size_t k = 0; k < gain->size(); ++k) {
180 RTC_DCHECK_LE(0.f, nearend_masking_margin * nearend[k]); 184 RTC_DCHECK_LE(0.f, nearend_masking_margin * nearend[k]);
181 if (echo[k] <= nearend_masking_margin * nearend[k]) { 185 if (echo[k] <= nearend_masking_margin * nearend[k]) {
182 (*gain)[k] = 1.f; 186 (*gain)[k] = 1.f;
183 } else { 187 } else {
184 (*gain)[k] = kEchoMaskingMargin * masker[k] * one_by_echo[k]; 188 (*gain)[k] = config.param.gain_mask.m1 * masker[k] * one_by_echo[k];
185 } 189 }
186 190
187 (*gain)[k] = std::min(std::max((*gain)[k], min_gain[k]), max_gain[k]); 191 (*gain)[k] = std::min(std::max((*gain)[k], min_gain[k]), max_gain[k]);
188 } 192 }
189 } 193 }
190 194
191 // Computes the signal output power that masks the echo signal. 195 // Computes the signal output power that masks the echo signal.
192 void MaskingPower(const std::array<float, kFftLengthBy2Plus1>& nearend, 196 void MaskingPower(const AudioProcessing::Config::EchoCanceller3& config,
197 const std::array<float, kFftLengthBy2Plus1>& nearend,
193 const std::array<float, kFftLengthBy2Plus1>& comfort_noise, 198 const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
194 const std::array<float, kFftLengthBy2Plus1>& last_masker, 199 const std::array<float, kFftLengthBy2Plus1>& last_masker,
195 const std::array<float, kFftLengthBy2Plus1>& gain, 200 const std::array<float, kFftLengthBy2Plus1>& gain,
196 std::array<float, kFftLengthBy2Plus1>* masker) { 201 std::array<float, kFftLengthBy2Plus1>* masker) {
197 std::array<float, kFftLengthBy2Plus1> side_band_masker; 202 std::array<float, kFftLengthBy2Plus1> side_band_masker;
198 for (size_t k = 0; k < gain.size(); ++k) { 203 for (size_t k = 0; k < gain.size(); ++k) {
199 side_band_masker[k] = nearend[k] * gain[k] + comfort_noise[k]; 204 side_band_masker[k] = nearend[k] * gain[k] + comfort_noise[k];
200 (*masker)[k] = comfort_noise[k] + 0.1f * last_masker[k]; 205 (*masker)[k] =
206 comfort_noise[k] + config.param.gain_mask.m4 * last_masker[k];
201 } 207 }
202 for (size_t k = 1; k < gain.size() - 1; ++k) { 208 for (size_t k = 1; k < gain.size() - 1; ++k) {
203 (*masker)[k] += 0.1f * (side_band_masker[k - 1] + side_band_masker[k + 1]); 209 (*masker)[k] += 0.1f * (side_band_masker[k - 1] + side_band_masker[k + 1]);
204 } 210 }
205 } 211 }
206 212
207 } // namespace 213 } // namespace
208 214
209 // TODO(peah): Add further optimizations, in particular for the divisions. 215 // TODO(peah): Add further optimizations, in particular for the divisions.
210 void SuppressionGain::LowerBandGain( 216 void SuppressionGain::LowerBandGain(
211 bool low_noise_render, 217 bool low_noise_render,
212 const rtc::Optional<int>& narrow_peak_band, 218 const rtc::Optional<int>& narrow_peak_band,
213 bool saturated_echo, 219 bool saturated_echo,
214 const std::array<float, kFftLengthBy2Plus1>& nearend, 220 const std::array<float, kFftLengthBy2Plus1>& nearend,
215 const std::array<float, kFftLengthBy2Plus1>& echo, 221 const std::array<float, kFftLengthBy2Plus1>& echo,
216 const std::array<float, kFftLengthBy2Plus1>& comfort_noise, 222 const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
217 std::array<float, kFftLengthBy2Plus1>* gain) { 223 std::array<float, kFftLengthBy2Plus1>* gain) {
218 // Count the number of blocks since saturation. 224 // Count the number of blocks since saturation.
219 no_saturation_counter_ = saturated_echo ? 0 : no_saturation_counter_ + 1; 225 no_saturation_counter_ = saturated_echo ? 0 : no_saturation_counter_ + 1;
220 226
221 // Precompute 1/echo (note that when the echo is zero, the precomputed value 227 // Precompute 1/echo (note that when the echo is zero, the precomputed value
222 // is never used). 228 // is never used).
223 std::array<float, kFftLengthBy2Plus1> one_by_echo; 229 std::array<float, kFftLengthBy2Plus1> one_by_echo;
224 std::transform(echo.begin(), echo.end(), one_by_echo.begin(), 230 std::transform(echo.begin(), echo.end(), one_by_echo.begin(),
225 [](float a) { return a > 0.f ? 1.f / a : 1.f; }); 231 [](float a) { return a > 0.f ? 1.f / a : 1.f; });
226 232
227 // Compute the minimum gain as the attenuating gain to put the signal just 233 // Compute the minimum gain as the attenuating gain to put the signal just
228 // above the zero sample values. 234 // above the zero sample values.
229 std::array<float, kFftLengthBy2Plus1> min_gain; 235 std::array<float, kFftLengthBy2Plus1> min_gain;
230 const float min_echo_power = low_noise_render ? 192.f : 64.f; 236 const float min_echo_power =
237 low_noise_render ? config_.param.echo_audibility.low_render_limit
238 : config_.param.echo_audibility.normal_render_limit;
231 if (no_saturation_counter_ > 10) { 239 if (no_saturation_counter_ > 10) {
232 for (size_t k = 0; k < nearend.size(); ++k) { 240 for (size_t k = 0; k < nearend.size(); ++k) {
233 const float denom = std::min(nearend[k], echo[k]); 241 const float denom = std::min(nearend[k], echo[k]);
234 min_gain[k] = denom > 0.f ? min_echo_power / denom : 1.f; 242 min_gain[k] = denom > 0.f ? min_echo_power / denom : 1.f;
235 min_gain[k] = std::min(min_gain[k], 1.f); 243 min_gain[k] = std::min(min_gain[k], 1.f);
236 } 244 }
237 } else { 245 } else {
238 min_gain.fill(0.f); 246 min_gain.fill(0.f);
239 } 247 }
240 248
241 // Compute the maximum gain by limiting the gain increase from the previous 249 // Compute the maximum gain by limiting the gain increase from the previous
242 // gain. 250 // gain.
243 std::array<float, kFftLengthBy2Plus1> max_gain; 251 std::array<float, kFftLengthBy2Plus1> max_gain;
244 for (size_t k = 0; k < gain->size(); ++k) { 252 for (size_t k = 0; k < gain->size(); ++k) {
245 max_gain[k] = 253 max_gain[k] =
246 std::min(std::max(last_gain_[k] * gain_increase_[k], 0.001f), 1.f); 254 std::min(std::max(last_gain_[k] * gain_increase_[k],
255 config_.param.gain_updates.floor_first_increase),
256 1.f);
247 } 257 }
248 258
249 // Iteratively compute the gain required to attenuate the echo to a non 259 // Iteratively compute the gain required to attenuate the echo to a non
250 // noticeable level. 260 // noticeable level.
251 gain->fill(0.f); 261 gain->fill(0.f);
252 for (int k = 0; k < 2; ++k) { 262 for (int k = 0; k < 2; ++k) {
253 std::array<float, kFftLengthBy2Plus1> masker; 263 std::array<float, kFftLengthBy2Plus1> masker;
254 MaskingPower(nearend, comfort_noise, last_masker_, *gain, &masker); 264 MaskingPower(config_, nearend, comfort_noise, last_masker_, *gain, &masker);
255 GainToNoAudibleEcho(low_noise_render, saturated_echo, nearend, echo, masker, 265 GainToNoAudibleEcho(config_, low_noise_render, saturated_echo, nearend,
256 min_gain, max_gain, one_by_echo, gain); 266 echo, masker, min_gain, max_gain, one_by_echo, gain);
257 AdjustForExternalFilters(gain); 267 AdjustForExternalFilters(gain);
258 if (narrow_peak_band) { 268 if (narrow_peak_band) {
259 NarrowBandAttenuation(*narrow_peak_band, gain); 269 NarrowBandAttenuation(*narrow_peak_band, gain);
260 } 270 }
261 } 271 }
262 272
263 // Update the allowed maximum gain increase. 273 // Update the allowed maximum gain increase.
264 UpdateMaxGainIncrease(no_saturation_counter_, low_noise_render, last_echo_, 274 UpdateMaxGainIncrease(config_, no_saturation_counter_, low_noise_render,
265 echo, last_gain_, *gain, &gain_increase_); 275 last_echo_, echo, last_gain_, *gain, &gain_increase_);
266 276
267 // Store data required for the gain computation of the next block. 277 // Store data required for the gain computation of the next block.
268 std::copy(echo.begin(), echo.end(), last_echo_.begin()); 278 std::copy(echo.begin(), echo.end(), last_echo_.begin());
269 std::copy(gain->begin(), gain->end(), last_gain_.begin()); 279 std::copy(gain->begin(), gain->end(), last_gain_.begin());
270 MaskingPower(nearend, comfort_noise, last_masker_, *gain, &last_masker_); 280 MaskingPower(config_, nearend, comfort_noise, last_masker_, *gain,
281 &last_masker_);
271 aec3::VectorMath(optimization_).Sqrt(*gain); 282 aec3::VectorMath(optimization_).Sqrt(*gain);
272 } 283 }
273 284
274 SuppressionGain::SuppressionGain(Aec3Optimization optimization) 285 SuppressionGain::SuppressionGain(
275 : optimization_(optimization) { 286 const AudioProcessing::Config::EchoCanceller3& config,
287 Aec3Optimization optimization)
288 : optimization_(optimization), config_(config) {
276 last_gain_.fill(1.f); 289 last_gain_.fill(1.f);
277 last_masker_.fill(0.f); 290 last_masker_.fill(0.f);
278 gain_increase_.fill(1.f); 291 gain_increase_.fill(1.f);
279 last_echo_.fill(0.f); 292 last_echo_.fill(0.f);
280 } 293 }
281 294
282 void SuppressionGain::GetGain( 295 void SuppressionGain::GetGain(
283 const std::array<float, kFftLengthBy2Plus1>& nearend, 296 const std::array<float, kFftLengthBy2Plus1>& nearend,
284 const std::array<float, kFftLengthBy2Plus1>& echo, 297 const std::array<float, kFftLengthBy2Plus1>& echo,
285 const std::array<float, kFftLengthBy2Plus1>& comfort_noise, 298 const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 } 340 }
328 341
329 constexpr float kThreshold = 50.f * 50.f * 64.f; 342 constexpr float kThreshold = 50.f * 50.f * 64.f;
330 const bool low_noise_render = 343 const bool low_noise_render =
331 average_power_ < kThreshold && x2_max < 3 * average_power_; 344 average_power_ < kThreshold && x2_max < 3 * average_power_;
332 average_power_ = average_power_ * 0.9f + x2_sum * 0.1f; 345 average_power_ = average_power_ * 0.9f + x2_sum * 0.1f;
333 return low_noise_render; 346 return low_noise_render;
334 } 347 }
335 348
336 } // namespace webrtc 349 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698