blob: c3053a4c419765c2bae38f02a9bf54b4ba65c5ba [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}
41} // namespace
Per Åhgrenb6b00dc2018-02-20 22:18:27 +010042
43EchoCanceller3Config::EchoCanceller3Config() = default;
Per Åhgren251c7352018-03-28 16:31:57 +020044EchoCanceller3Config::EchoCanceller3Config(const EchoCanceller3Config& e) =
45 default;
Per Åhgren398689f2018-08-23 11:38:27 +020046EchoCanceller3Config::Delay::Delay() = default;
47EchoCanceller3Config::Delay::Delay(const EchoCanceller3Config::Delay& e) =
48 default;
49
Jesús de Vicente Peñadd092872018-05-25 16:55:11 +020050EchoCanceller3Config::EchoModel::EchoModel() = default;
51EchoCanceller3Config::EchoModel::EchoModel(
52 const EchoCanceller3Config::EchoModel& e) = default;
53
Per Åhgren524e8782018-08-24 22:48:49 +020054EchoCanceller3Config::Suppressor::Suppressor() = default;
55EchoCanceller3Config::Suppressor::Suppressor(
56 const EchoCanceller3Config::Suppressor& e) = default;
57
58EchoCanceller3Config::Suppressor::MaskingThresholds::MaskingThresholds(
59 float enr_transparent,
60 float enr_suppress,
61 float emr_transparent)
62 : enr_transparent(enr_transparent),
63 enr_suppress(enr_suppress),
64 emr_transparent(emr_transparent) {}
65EchoCanceller3Config::Suppressor::Suppressor::MaskingThresholds::
66 MaskingThresholds(
67 const EchoCanceller3Config::Suppressor::MaskingThresholds& e) = default;
68
69EchoCanceller3Config::Suppressor::Tuning::Tuning(MaskingThresholds mask_lf,
70 MaskingThresholds mask_hf,
71 float max_inc_factor,
72 float max_dec_factor_lf)
73 : mask_lf(mask_lf),
74 mask_hf(mask_hf),
75 max_inc_factor(max_inc_factor),
76 max_dec_factor_lf(max_dec_factor_lf) {}
77EchoCanceller3Config::Suppressor::Tuning::Tuning(
78 const EchoCanceller3Config::Suppressor::Tuning& e) = default;
79
Sam Zackrissona4c85142018-10-10 10:44:43 +020080bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) {
81 RTC_DCHECK(config);
82 EchoCanceller3Config* c = config;
83 bool res = true;
84
85 if (c->delay.down_sampling_factor != 4 &&
86 c->delay.down_sampling_factor != 8) {
87 c->delay.down_sampling_factor = 4;
88 res = false;
89 }
Sam Zackrissona4c85142018-10-10 10:44:43 +020090 if (c->delay.delay_headroom_blocks <= 1 &&
Gustaf Ullberg9bf67ea2019-02-12 12:23:02 +010091 c->delay.hysteresis_limit_2_blocks == 1) {
92 c->delay.hysteresis_limit_2_blocks = 0;
Sam Zackrissona4c85142018-10-10 10:44:43 +020093 res = false;
94 }
Sam Zackrisson877dc892018-10-23 14:17:38 +020095 res = res & Limit(&c->delay.default_delay, 0, 5000);
96 res = res & Limit(&c->delay.num_filters, 0, 5000);
Sam Zackrisson877dc892018-10-23 14:17:38 +020097 res = res & Limit(&c->delay.delay_headroom_blocks, 0, 5000);
98 res = res & Limit(&c->delay.hysteresis_limit_1_blocks, 0, 5000);
99 res = res & Limit(&c->delay.hysteresis_limit_2_blocks, 0, 5000);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200100 res = res & Limit(&c->delay.fixed_capture_delay_samples, 0, 5000);
101 res = res & Limit(&c->delay.delay_estimate_smoothing, 0.f, 1.f);
102 res = res & Limit(&c->delay.delay_candidate_detection_threshold, 0.f, 1.f);
103 res = res & Limit(&c->delay.delay_selection_thresholds.initial, 1, 250);
104 res = res & Limit(&c->delay.delay_selection_thresholds.converged, 1, 250);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200105
Sam Zackrisson877dc892018-10-23 14:17:38 +0200106 res = res & Limit(&c->filter.main.length_blocks, 1, 50);
107 res = res & Limit(&c->filter.main.leakage_converged, 0.f, 1000.f);
108 res = res & Limit(&c->filter.main.leakage_diverged, 0.f, 1000.f);
109 res = res & Limit(&c->filter.main.error_floor, 0.f, 1000.f);
110 res = res & Limit(&c->filter.main.error_ceil, 0.f, 100000000.f);
111 res = res & Limit(&c->filter.main.noise_gate, 0.f, 100000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200112
Sam Zackrisson877dc892018-10-23 14:17:38 +0200113 res = res & Limit(&c->filter.main_initial.length_blocks, 1, 50);
114 res = res & Limit(&c->filter.main_initial.leakage_converged, 0.f, 1000.f);
115 res = res & Limit(&c->filter.main_initial.leakage_diverged, 0.f, 1000.f);
116 res = res & Limit(&c->filter.main_initial.error_floor, 0.f, 1000.f);
117 res = res & Limit(&c->filter.main_initial.error_ceil, 0.f, 100000000.f);
118 res = res & Limit(&c->filter.main_initial.noise_gate, 0.f, 100000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200119
120 if (c->filter.main.length_blocks < c->filter.main_initial.length_blocks) {
121 c->filter.main_initial.length_blocks = c->filter.main.length_blocks;
122 res = false;
123 }
124
Sam Zackrisson877dc892018-10-23 14:17:38 +0200125 res = res & Limit(&c->filter.shadow.length_blocks, 1, 50);
126 res = res & Limit(&c->filter.shadow.rate, 0.f, 1.f);
127 res = res & Limit(&c->filter.shadow.noise_gate, 0.f, 100000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200128
Sam Zackrisson877dc892018-10-23 14:17:38 +0200129 res = res & Limit(&c->filter.shadow_initial.length_blocks, 1, 50);
130 res = res & Limit(&c->filter.shadow_initial.rate, 0.f, 1.f);
131 res = res & Limit(&c->filter.shadow_initial.noise_gate, 0.f, 100000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200132
133 if (c->filter.shadow.length_blocks < c->filter.shadow_initial.length_blocks) {
134 c->filter.shadow_initial.length_blocks = c->filter.shadow.length_blocks;
135 res = false;
136 }
137
Sam Zackrisson877dc892018-10-23 14:17:38 +0200138 res = res & Limit(&c->filter.config_change_duration_blocks, 0, 100000);
139 res = res & Limit(&c->filter.initial_state_seconds, 0.f, 100.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200140
Sam Zackrisson877dc892018-10-23 14:17:38 +0200141 res = res & Limit(&c->erle.min, 1.f, 100000.f);
142 res = res & Limit(&c->erle.max_l, 1.f, 100000.f);
143 res = res & Limit(&c->erle.max_h, 1.f, 100000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200144 if (c->erle.min > c->erle.max_l || c->erle.min > c->erle.max_h) {
145 c->erle.min = std::min(c->erle.max_l, c->erle.max_h);
146 res = false;
147 }
Jesús de Vicente Peña44974e12018-11-20 12:54:23 +0100148 res = res & Limit(&c->erle.num_sections, 1, c->filter.main.length_blocks);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200149
Sam Zackrisson877dc892018-10-23 14:17:38 +0200150 res = res & Limit(&c->ep_strength.lf, 0.f, 1000000.f);
151 res = res & Limit(&c->ep_strength.mf, 0.f, 1000000.f);
152 res = res & Limit(&c->ep_strength.hf, 0.f, 1000000.f);
Jesús de Vicente Peña44974e12018-11-20 12:54:23 +0100153 res = res & Limit(&c->ep_strength.default_len, -1.f, 1.f);
Sam Zackrisson8ee06a72018-10-23 12:32:42 +0200154
155 res =
Sam Zackrisson877dc892018-10-23 14:17:38 +0200156 res & Limit(&c->echo_audibility.low_render_limit, 0.f, 32768.f * 32768.f);
157 res = res &
158 Limit(&c->echo_audibility.normal_render_limit, 0.f, 32768.f * 32768.f);
159 res = res & Limit(&c->echo_audibility.floor_power, 0.f, 32768.f * 32768.f);
160 res = res & Limit(&c->echo_audibility.audibility_threshold_lf, 0.f,
161 32768.f * 32768.f);
162 res = res & Limit(&c->echo_audibility.audibility_threshold_mf, 0.f,
163 32768.f * 32768.f);
164 res = res & Limit(&c->echo_audibility.audibility_threshold_hf, 0.f,
165 32768.f * 32768.f);
166
167 res = res &
168 Limit(&c->render_levels.active_render_limit, 0.f, 32768.f * 32768.f);
169 res = res & Limit(&c->render_levels.poor_excitation_render_limit, 0.f,
170 32768.f * 32768.f);
171 res = res & Limit(&c->render_levels.poor_excitation_render_limit_ds8, 0.f,
172 32768.f * 32768.f);
173
174 res =
175 res & Limit(&c->echo_removal_control.gain_rampup.initial_gain, 0.f, 1.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200176 res = res & Limit(&c->echo_removal_control.gain_rampup.non_zero_gain_blocks,
177 0, 100000);
178 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200179 Limit(&c->echo_removal_control.gain_rampup.full_gain_blocks, 0, 100000);
180
Sam Zackrisson877dc892018-10-23 14:17:38 +0200181 res = res & Limit(&c->echo_model.noise_floor_hold, 0, 1000);
182 res = res & Limit(&c->echo_model.min_noise_floor_power, 0, 2000000.f);
183 res = res & Limit(&c->echo_model.stationary_gate_slope, 0, 1000000.f);
184 res = res & Limit(&c->echo_model.noise_gate_power, 0, 1000000.f);
185 res = res & Limit(&c->echo_model.noise_gate_slope, 0, 1000000.f);
186 res = res & Limit(&c->echo_model.render_pre_window_size, 0, 100);
187 res = res & Limit(&c->echo_model.render_post_window_size, 0, 100);
188 res = res & Limit(&c->echo_model.render_pre_window_size_init, 0, 100);
189 res = res & Limit(&c->echo_model.render_post_window_size_init, 0, 100);
190 res = res & Limit(&c->echo_model.nonlinear_hold, 0, 100);
191 res = res & Limit(&c->echo_model.nonlinear_release, 0, 1.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200192
Sam Zackrisson877dc892018-10-23 14:17:38 +0200193 res = res & Limit(&c->suppressor.nearend_average_blocks, 1, 5000);
194
195 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200196 Limit(&c->suppressor.normal_tuning.mask_lf.enr_transparent, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200197 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200198 Limit(&c->suppressor.normal_tuning.mask_lf.enr_suppress, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200199 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200200 Limit(&c->suppressor.normal_tuning.mask_lf.emr_transparent, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200201 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200202 Limit(&c->suppressor.normal_tuning.mask_hf.enr_transparent, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200203 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200204 Limit(&c->suppressor.normal_tuning.mask_hf.enr_suppress, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200205 res = res &
Sam Zackrissona4c85142018-10-10 10:44:43 +0200206 Limit(&c->suppressor.normal_tuning.mask_hf.emr_transparent, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200207 res = res & Limit(&c->suppressor.normal_tuning.max_inc_factor, 0.f, 100.f);
208 res = res & Limit(&c->suppressor.normal_tuning.max_dec_factor_lf, 0.f, 100.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200209
Sam Zackrisson877dc892018-10-23 14:17:38 +0200210 res = res & Limit(&c->suppressor.nearend_tuning.mask_lf.enr_transparent, 0.f,
211 100.f);
212 res = res &
Sam Zackrisson848273a2018-10-23 12:13:42 +0000213 Limit(&c->suppressor.nearend_tuning.mask_lf.enr_suppress, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200214 res = res & Limit(&c->suppressor.nearend_tuning.mask_lf.emr_transparent, 0.f,
215 100.f);
216 res = res & Limit(&c->suppressor.nearend_tuning.mask_hf.enr_transparent, 0.f,
217 100.f);
218 res = res &
Sam Zackrisson848273a2018-10-23 12:13:42 +0000219 Limit(&c->suppressor.nearend_tuning.mask_hf.enr_suppress, 0.f, 100.f);
Sam Zackrisson877dc892018-10-23 14:17:38 +0200220 res = res & Limit(&c->suppressor.nearend_tuning.mask_hf.emr_transparent, 0.f,
221 100.f);
222 res = res & Limit(&c->suppressor.nearend_tuning.max_inc_factor, 0.f, 100.f);
Sam Zackrisson848273a2018-10-23 12:13:42 +0000223 res =
Sam Zackrisson877dc892018-10-23 14:17:38 +0200224 res & Limit(&c->suppressor.nearend_tuning.max_dec_factor_lf, 0.f, 100.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200225
Sam Zackrisson877dc892018-10-23 14:17:38 +0200226 res = res & Limit(&c->suppressor.dominant_nearend_detection.enr_threshold,
227 0.f, 1000000.f);
228 res = res & Limit(&c->suppressor.dominant_nearend_detection.snr_threshold,
229 0.f, 1000000.f);
230 res = res & Limit(&c->suppressor.dominant_nearend_detection.hold_duration, 0,
231 10000);
232 res = res & Limit(&c->suppressor.dominant_nearend_detection.trigger_threshold,
233 0, 10000);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200234
Sam Zackrisson877dc892018-10-23 14:17:38 +0200235 res = res & Limit(&c->suppressor.high_bands_suppression.enr_threshold, 0.f,
236 1000000.f);
237 res = res & Limit(&c->suppressor.high_bands_suppression.max_gain_during_echo,
238 0.f, 1.f);
Sam Zackrisson848273a2018-10-23 12:13:42 +0000239
Sam Zackrisson877dc892018-10-23 14:17:38 +0200240 res = res & Limit(&c->suppressor.floor_first_increase, 0.f, 1000000.f);
Sam Zackrissona4c85142018-10-10 10:44:43 +0200241
Jesús de Vicente Peña44974e12018-11-20 12:54:23 +0100242 if (c->delay.delay_headroom_blocks >
243 c->filter.main_initial.length_blocks - 1) {
244 c->delay.delay_headroom_blocks = c->filter.main_initial.length_blocks - 1;
245 res = false;
246 }
247
Sam Zackrissona4c85142018-10-10 10:44:43 +0200248 return res;
249}
Per Åhgrenb6b00dc2018-02-20 22:18:27 +0100250} // namespace webrtc