blob: 17af8f8023a5c979a4dc671537a02bf3d3caf132 [file] [log] [blame]
Per Åhgrenb6b00dc2018-02-20 22:18:27 +01001/*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10#include "api/audio/echo_canceller3_config.h"
11
Sam Zackrissona4c85142018-10-10 10:44:43 +020012#include <algorithm>
Sam Zackrisson877dc892018-10-23 14:17:38 +020013#include <cmath>
Sam Zackrissona4c85142018-10-10 10:44:43 +020014
Yves Gerey988cc082018-10-23 12:03:01 +020015#include "rtc_base/checks.h"
Sam Zackrissona4c85142018-10-10 10:44:43 +020016#include "rtc_base/numerics/safe_minmax.h"
17
Per Åhgrenb6b00dc2018-02-20 22:18:27 +010018namespace webrtc {
Sam Zackrissona4c85142018-10-10 10:44:43 +020019namespace {
20bool Limit(float* value, float min, float max) {
21 float clamped = rtc::SafeClamp(*value, min, max);
Sam Zackrisson877dc892018-10-23 14:17:38 +020022 clamped = std::isfinite(clamped) ? clamped : min;
Sam Zackrissona4c85142018-10-10 10:44:43 +020023 bool res = *value == clamped;
24 *value = clamped;
25 return res;
26}
27
28bool Limit(size_t* value, size_t min, size_t max) {
29 size_t clamped = rtc::SafeClamp(*value, min, max);
30 bool res = *value == clamped;
31 *value = clamped;
32 return res;
33}
34
35bool Limit(int* value, int min, int max) {
36 int clamped = rtc::SafeClamp(*value, min, max);
37 bool res = *value == clamped;
38 *value = clamped;
39 return res;
40}
Per Åhgren9136abb2019-12-19 10:38:01 +010041
42bool FloorLimit(size_t* value, size_t min) {
43 size_t clamped = *value >= min ? *value : min;
44 bool res = *value == clamped;
45 *value = clamped;
46 return res;
47}
48
Sam Zackrissona4c85142018-10-10 10:44:43 +020049} // namespace
Per Åhgrenb6b00dc2018-02-20 22:18:27 +010050
51EchoCanceller3Config::EchoCanceller3Config() = default;
Per Åhgren251c7352018-03-28 16:31:57 +020052EchoCanceller3Config::EchoCanceller3Config(const EchoCanceller3Config& e) =
53 default;
Artem Titov5d3a4182019-12-03 11:13:26 +010054EchoCanceller3Config& EchoCanceller3Config::operator=(
55 const EchoCanceller3Config& e) = default;
Per Åhgren398689f2018-08-23 11:38:27 +020056EchoCanceller3Config::Delay::Delay() = default;
57EchoCanceller3Config::Delay::Delay(const EchoCanceller3Config::Delay& e) =
58 default;
Artem Titov5d3a4182019-12-03 11:13:26 +010059EchoCanceller3Config::Delay& EchoCanceller3Config::Delay::operator=(
60 const Delay& e) = default;
Per Åhgren398689f2018-08-23 11:38:27 +020061
Jesús de Vicente Peñadd092872018-05-25 16:55:11 +020062EchoCanceller3Config::EchoModel::EchoModel() = default;
63EchoCanceller3Config::EchoModel::EchoModel(
64 const EchoCanceller3Config::EchoModel& e) = default;
Artem Titov5d3a4182019-12-03 11:13:26 +010065EchoCanceller3Config::EchoModel& EchoCanceller3Config::EchoModel::operator=(
66 const EchoModel& e) = default;
Jesús de Vicente Peñadd092872018-05-25 16:55:11 +020067
Per Åhgren524e8782018-08-24 22:48:49 +020068EchoCanceller3Config::Suppressor::Suppressor() = default;
69EchoCanceller3Config::Suppressor::Suppressor(
70 const EchoCanceller3Config::Suppressor& e) = default;
Artem Titov5d3a4182019-12-03 11:13:26 +010071EchoCanceller3Config::Suppressor& EchoCanceller3Config::Suppressor::operator=(
72 const Suppressor& e) = default;
Per Åhgren524e8782018-08-24 22:48:49 +020073
74EchoCanceller3Config::Suppressor::MaskingThresholds::MaskingThresholds(
75 float enr_transparent,
76 float enr_suppress,
77 float emr_transparent)
78 : enr_transparent(enr_transparent),
79 enr_suppress(enr_suppress),
80 emr_transparent(emr_transparent) {}
Artem Titov5d3a4182019-12-03 11:13:26 +010081EchoCanceller3Config::Suppressor::MaskingThresholds::MaskingThresholds(
82 const EchoCanceller3Config::Suppressor::MaskingThresholds& e) = default;
83EchoCanceller3Config::Suppressor::MaskingThresholds&
84EchoCanceller3Config::Suppressor::MaskingThresholds::operator=(
85 const MaskingThresholds& e) = default;
Per Åhgren524e8782018-08-24 22:48:49 +020086
87EchoCanceller3Config::Suppressor::Tuning::Tuning(MaskingThresholds mask_lf,
88 MaskingThresholds mask_hf,
89 float max_inc_factor,
90 float max_dec_factor_lf)
91 : mask_lf(mask_lf),
92 mask_hf(mask_hf),
93 max_inc_factor(max_inc_factor),
94 max_dec_factor_lf(max_dec_factor_lf) {}
95EchoCanceller3Config::Suppressor::Tuning::Tuning(
96 const EchoCanceller3Config::Suppressor::Tuning& e) = default;
Artem Titov5d3a4182019-12-03 11:13:26 +010097EchoCanceller3Config::Suppressor::Tuning&
98EchoCanceller3Config::Suppressor::Tuning::operator=(const Tuning& e) = default;
Per Åhgren524e8782018-08-24 22:48:49 +020099
Sam Zackrissona4c85142018-10-10 10:44:43 +0200100bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) {
101 RTC_DCHECK(config);
102 EchoCanceller3Config* c = config;
103 bool res = true;
104
105 if (c->delay.down_sampling_factor != 4 &&
106 c->delay.down_sampling_factor != 8) {
107 c->delay.down_sampling_factor = 4;
108 res = false;
109 }
Gustaf Ullberg9249fbf2019-03-14 11:24:54 +0100110
Sam Zackrisson877dc892018-10-23 14:17:38 +0200111 res = res & Limit(&c->delay.default_delay, 0, 5000);
112 res = res & Limit(&c->delay.num_filters, 0, 5000);
Gustaf Ullberg9249fbf2019-03-14 11:24:54 +0100113 res = res & Limit(&c->delay.delay_headroom_samples, 0, 5000);
114 res = res & Limit(&c->delay.hysteresis_limit_blocks, 0, 5000);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200115 res = res & Limit(&c->delay.fixed_capture_delay_samples, 0, 5000);
116 res = res & Limit(&c->delay.delay_estimate_smoothing, 0.f, 1.f);
117 res = res & Limit(&c->delay.delay_candidate_detection_threshold, 0.f, 1.f);
118 res = res & Limit(&c->delay.delay_selection_thresholds.initial, 1, 250);
119 res = res & Limit(&c->delay.delay_selection_thresholds.converged, 1, 250);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200120
Per Åhgren9136abb2019-12-19 10:38:01 +0100121 res = res & FloorLimit(&c->filter.main.length_blocks, 1);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200122 res = res & Limit(&c->filter.main.leakage_converged, 0.f, 1000.f);
123 res = res & Limit(&c->filter.main.leakage_diverged, 0.f, 1000.f);
124 res = res & Limit(&c->filter.main.error_floor, 0.f, 1000.f);
125 res = res & Limit(&c->filter.main.error_ceil, 0.f, 100000000.f);
126 res = res & Limit(&c->filter.main.noise_gate, 0.f, 100000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200127
Per Åhgren9136abb2019-12-19 10:38:01 +0100128 res = res & FloorLimit(&c->filter.main_initial.length_blocks, 1);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200129 res = res & Limit(&c->filter.main_initial.leakage_converged, 0.f, 1000.f);
130 res = res & Limit(&c->filter.main_initial.leakage_diverged, 0.f, 1000.f);
131 res = res & Limit(&c->filter.main_initial.error_floor, 0.f, 1000.f);
132 res = res & Limit(&c->filter.main_initial.error_ceil, 0.f, 100000000.f);
133 res = res & Limit(&c->filter.main_initial.noise_gate, 0.f, 100000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200134
135 if (c->filter.main.length_blocks < c->filter.main_initial.length_blocks) {
136 c->filter.main_initial.length_blocks = c->filter.main.length_blocks;
137 res = false;
138 }
139
Per Åhgrenff045112020-03-20 11:20:39 +0100140 res = res & FloorLimit(&c->filter.refined.length_blocks, 1);
141 res = res & Limit(&c->filter.refined.leakage_converged, 0.f, 1000.f);
142 res = res & Limit(&c->filter.refined.leakage_diverged, 0.f, 1000.f);
143 res = res & Limit(&c->filter.refined.error_floor, 0.f, 1000.f);
144 res = res & Limit(&c->filter.refined.error_ceil, 0.f, 100000000.f);
145 res = res & Limit(&c->filter.refined.noise_gate, 0.f, 100000000.f);
146
147 res = res & FloorLimit(&c->filter.refined_initial.length_blocks, 1);
148 res = res & Limit(&c->filter.refined_initial.leakage_converged, 0.f, 1000.f);
149 res = res & Limit(&c->filter.refined_initial.leakage_diverged, 0.f, 1000.f);
150 res = res & Limit(&c->filter.refined_initial.error_floor, 0.f, 1000.f);
151 res = res & Limit(&c->filter.refined_initial.error_ceil, 0.f, 100000000.f);
152 res = res & Limit(&c->filter.refined_initial.noise_gate, 0.f, 100000000.f);
153
154 if (c->filter.refined.length_blocks <
155 c->filter.refined_initial.length_blocks) {
156 c->filter.refined_initial.length_blocks = c->filter.refined.length_blocks;
157 res = false;
158 }
159
Per Åhgren9136abb2019-12-19 10:38:01 +0100160 res = res & FloorLimit(&c->filter.shadow.length_blocks, 1);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200161 res = res & Limit(&c->filter.shadow.rate, 0.f, 1.f);
162 res = res & Limit(&c->filter.shadow.noise_gate, 0.f, 100000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200163
Per Åhgren9136abb2019-12-19 10:38:01 +0100164 res = res & FloorLimit(&c->filter.shadow_initial.length_blocks, 1);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200165 res = res & Limit(&c->filter.shadow_initial.rate, 0.f, 1.f);
166 res = res & Limit(&c->filter.shadow_initial.noise_gate, 0.f, 100000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200167
168 if (c->filter.shadow.length_blocks < c->filter.shadow_initial.length_blocks) {
169 c->filter.shadow_initial.length_blocks = c->filter.shadow.length_blocks;
170 res = false;
171 }
172
Per Åhgren9d661982020-03-20 11:26:48 +0100173 res = res & FloorLimit(&c->filter.coarse.length_blocks, 1);
174 res = res & Limit(&c->filter.coarse.rate, 0.f, 1.f);
175 res = res & Limit(&c->filter.coarse.noise_gate, 0.f, 100000000.f);
176
177 res = res & FloorLimit(&c->filter.coarse_initial.length_blocks, 1);
178 res = res & Limit(&c->filter.coarse_initial.rate, 0.f, 1.f);
179 res = res & Limit(&c->filter.coarse_initial.noise_gate, 0.f, 100000000.f);
180
181 if (c->filter.coarse.length_blocks < c->filter.coarse_initial.length_blocks) {
182 c->filter.coarse_initial.length_blocks = c->filter.coarse.length_blocks;
183 res = false;
184 }
185
Sam Zackrisson877dc892018-10-23 14:17:38 +0200186 res = res & Limit(&c->filter.config_change_duration_blocks, 0, 100000);
187 res = res & Limit(&c->filter.initial_state_seconds, 0.f, 100.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200188
Sam Zackrisson877dc892018-10-23 14:17:38 +0200189 res = res & Limit(&c->erle.min, 1.f, 100000.f);
190 res = res & Limit(&c->erle.max_l, 1.f, 100000.f);
191 res = res & Limit(&c->erle.max_h, 1.f, 100000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200192 if (c->erle.min > c->erle.max_l || c->erle.min > c->erle.max_h) {
193 c->erle.min = std::min(c->erle.max_l, c->erle.max_h);
194 res = false;
195 }
Jesús de Vicente Peña44974e12018-11-20 12:54:23 +0100196 res = res & Limit(&c->erle.num_sections, 1, c->filter.main.length_blocks);
Per Åhgrenff045112020-03-20 11:20:39 +0100197 res = res & Limit(&c->erle.num_sections, 1, c->filter.refined.length_blocks);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200198
Per Åhgrene8efbbd2019-03-14 11:29:39 +0100199 res = res & Limit(&c->ep_strength.default_gain, 0.f, 1000000.f);
Jesús de Vicente Peña44974e12018-11-20 12:54:23 +0100200 res = res & Limit(&c->ep_strength.default_len, -1.f, 1.f);
Sam Zackrisson8ee06a72018-10-23 12:32:42 +0200201
202 res =
Sam Zackrisson877dc892018-10-23 14:17:38 +0200203 res & Limit(&c->echo_audibility.low_render_limit, 0.f, 32768.f * 32768.f);
204 res = res &
205 Limit(&c->echo_audibility.normal_render_limit, 0.f, 32768.f * 32768.f);
206 res = res & Limit(&c->echo_audibility.floor_power, 0.f, 32768.f * 32768.f);
207 res = res & Limit(&c->echo_audibility.audibility_threshold_lf, 0.f,
208 32768.f * 32768.f);
209 res = res & Limit(&c->echo_audibility.audibility_threshold_mf, 0.f,
210 32768.f * 32768.f);
211 res = res & Limit(&c->echo_audibility.audibility_threshold_hf, 0.f,
212 32768.f * 32768.f);
213
214 res = res &
215 Limit(&c->render_levels.active_render_limit, 0.f, 32768.f * 32768.f);
216 res = res & Limit(&c->render_levels.poor_excitation_render_limit, 0.f,
217 32768.f * 32768.f);
218 res = res & Limit(&c->render_levels.poor_excitation_render_limit_ds8, 0.f,
219 32768.f * 32768.f);
220
Sam Zackrisson877dc892018-10-23 14:17:38 +0200221 res = res & Limit(&c->echo_model.noise_floor_hold, 0, 1000);
222 res = res & Limit(&c->echo_model.min_noise_floor_power, 0, 2000000.f);
223 res = res & Limit(&c->echo_model.stationary_gate_slope, 0, 1000000.f);
224 res = res & Limit(&c->echo_model.noise_gate_power, 0, 1000000.f);
225 res = res & Limit(&c->echo_model.noise_gate_slope, 0, 1000000.f);
226 res = res & Limit(&c->echo_model.render_pre_window_size, 0, 100);
227 res = res & Limit(&c->echo_model.render_post_window_size, 0, 100);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200228
Per Åhgrena388b752020-03-25 07:31:47 +0100229 res = res & Limit(&c->comfort_noise.noise_floor_dbfs, -200.f, 0.f);
230
Sam Zackrisson877dc892018-10-23 14:17:38 +0200231 res = res & Limit(&c->suppressor.nearend_average_blocks, 1, 5000);
232
233 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200234 Limit(&c->suppressor.normal_tuning.mask_lf.enr_transparent, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200235 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200236 Limit(&c->suppressor.normal_tuning.mask_lf.enr_suppress, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200237 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200238 Limit(&c->suppressor.normal_tuning.mask_lf.emr_transparent, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200239 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200240 Limit(&c->suppressor.normal_tuning.mask_hf.enr_transparent, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200241 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200242 Limit(&c->suppressor.normal_tuning.mask_hf.enr_suppress, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200243 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200244 Limit(&c->suppressor.normal_tuning.mask_hf.emr_transparent, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200245 res = res & Limit(&c->suppressor.normal_tuning.max_inc_factor, 0.f, 100.f);
246 res = res & Limit(&c->suppressor.normal_tuning.max_dec_factor_lf, 0.f, 100.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200247
Sam Zackrisson877dc892018-10-23 14:17:38 +0200248 res = res & Limit(&c->suppressor.nearend_tuning.mask_lf.enr_transparent, 0.f,
249 100.f);
250 res = res &
Sam Zackrisson848273a2018-10-23 12:13:42 +0000251 Limit(&c->suppressor.nearend_tuning.mask_lf.enr_suppress, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200252 res = res & Limit(&c->suppressor.nearend_tuning.mask_lf.emr_transparent, 0.f,
253 100.f);
254 res = res & Limit(&c->suppressor.nearend_tuning.mask_hf.enr_transparent, 0.f,
255 100.f);
256 res = res &
Sam Zackrisson848273a2018-10-23 12:13:42 +0000257 Limit(&c->suppressor.nearend_tuning.mask_hf.enr_suppress, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200258 res = res & Limit(&c->suppressor.nearend_tuning.mask_hf.emr_transparent, 0.f,
259 100.f);
260 res = res & Limit(&c->suppressor.nearend_tuning.max_inc_factor, 0.f, 100.f);
Sam Zackrisson848273a2018-10-23 12:13:42 +0000261 res =
Sam Zackrisson877dc892018-10-23 14:17:38 +0200262 res & Limit(&c->suppressor.nearend_tuning.max_dec_factor_lf, 0.f, 100.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200263
Sam Zackrisson877dc892018-10-23 14:17:38 +0200264 res = res & Limit(&c->suppressor.dominant_nearend_detection.enr_threshold,
265 0.f, 1000000.f);
266 res = res & Limit(&c->suppressor.dominant_nearend_detection.snr_threshold,
267 0.f, 1000000.f);
268 res = res & Limit(&c->suppressor.dominant_nearend_detection.hold_duration, 0,
269 10000);
270 res = res & Limit(&c->suppressor.dominant_nearend_detection.trigger_threshold,
271 0, 10000);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200272
Gustaf Ullbergf534a642019-11-25 16:13:58 +0100273 res = res &
274 Limit(&c->suppressor.subband_nearend_detection.nearend_average_blocks,
275 1, 1024);
276 res =
277 res & Limit(&c->suppressor.subband_nearend_detection.subband1.low, 0, 65);
278 res = res & Limit(&c->suppressor.subband_nearend_detection.subband1.high,
279 c->suppressor.subband_nearend_detection.subband1.low, 65);
280 res =
281 res & Limit(&c->suppressor.subband_nearend_detection.subband2.low, 0, 65);
282 res = res & Limit(&c->suppressor.subband_nearend_detection.subband2.high,
283 c->suppressor.subband_nearend_detection.subband2.low, 65);
284 res = res & Limit(&c->suppressor.subband_nearend_detection.nearend_threshold,
285 0.f, 1.e24f);
286 res = res & Limit(&c->suppressor.subband_nearend_detection.snr_threshold, 0.f,
287 1.e24f);
288
Sam Zackrisson877dc892018-10-23 14:17:38 +0200289 res = res & Limit(&c->suppressor.high_bands_suppression.enr_threshold, 0.f,
290 1000000.f);
291 res = res & Limit(&c->suppressor.high_bands_suppression.max_gain_during_echo,
292 0.f, 1.f);
Per Åhgren17e4c582019-11-27 08:13:24 +0100293 res = res & Limit(&c->suppressor.high_bands_suppression
294 .anti_howling_activation_threshold,
295 0.f, 32768.f * 32768.f);
296 res = res & Limit(&c->suppressor.high_bands_suppression.anti_howling_gain,
297 0.f, 1.f);
Sam Zackrisson848273a2018-10-23 12:13:42 +0000298
Sam Zackrisson877dc892018-10-23 14:17:38 +0200299 res = res & Limit(&c->suppressor.floor_first_increase, 0.f, 1000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200300
301 return res;
302}
Per Åhgrenb6b00dc2018-02-20 22:18:27 +0100303} // namespace webrtc