blob: 181b649f6d0679404be9d53da982581e47854b54 [file] [log] [blame]
peahe0eae3c2016-12-14 01:16:23 -08001/*
2 * Copyright (c) 2016 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 */
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020010#include "modules/audio_processing/aec3/echo_canceller3.h"
peahe0eae3c2016-12-14 01:16:23 -080011
Yves Gerey988cc082018-10-23 12:03:01 +020012#include <algorithm>
13#include <utility>
14
15#include "modules/audio_processing/aec3/aec3_common.h"
Per Åhgren0aefbf02019-08-23 21:29:17 +020016#include "modules/audio_processing/high_pass_filter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/audio_processing/logging/apm_data_dumper.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/atomic_ops.h"
Per Åhgren80e52162020-04-06 14:57:52 +020019#include "rtc_base/experiments/field_trial_parser.h"
Per Åhgrenc20a19c2019-11-13 11:12:29 +010020#include "rtc_base/logging.h"
Gustaf Ullberg9249fbf2019-03-14 11:24:54 +010021#include "system_wrappers/include/field_trial.h"
peahe0eae3c2016-12-14 01:16:23 -080022
23namespace webrtc {
24
peahd0263542017-01-03 04:20:34 -080025namespace {
26
peahcf02cf12017-04-05 14:18:07 -070027enum class EchoCanceller3ApiCall { kCapture, kRender };
28
peahd0263542017-01-03 04:20:34 -080029bool DetectSaturation(rtc::ArrayView<const float> y) {
30 for (auto y_k : y) {
peah522d71b2017-02-23 05:16:26 -080031 if (y_k >= 32700.0f || y_k <= -32700.0f) {
peahd0263542017-01-03 04:20:34 -080032 return true;
33 }
34 }
35 return false;
36}
37
Per Åhgren80e52162020-04-06 14:57:52 +020038// Retrieves a value from a field trial if it is available. If no value is
39// present, the default value is returned. If the retrieved value is beyond the
40// specified limits, the default value is returned instead.
41void RetrieveFieldTrialValue(const char* trial_name,
42 float min,
43 float max,
44 float* value_to_update) {
45 const std::string field_trial_str = field_trial::FindFullName(trial_name);
46
47 FieldTrialParameter<double> field_trial_param(/*key=*/"", *value_to_update);
48
49 ParseFieldTrial({&field_trial_param}, field_trial_str);
50 float field_trial_value = static_cast<float>(field_trial_param.Get());
51
Gustaf Ullberg398def62021-05-19 15:25:18 +020052 if (field_trial_value >= min && field_trial_value <= max &&
53 field_trial_value != *value_to_update) {
54 RTC_LOG(LS_INFO) << "Key " << trial_name
55 << " changing AEC3 parameter value from "
56 << *value_to_update << " to " << field_trial_value;
Per Åhgren80e52162020-04-06 14:57:52 +020057 *value_to_update = field_trial_value;
58 }
59}
60
61void RetrieveFieldTrialValue(const char* trial_name,
62 int min,
63 int max,
64 int* value_to_update) {
65 const std::string field_trial_str = field_trial::FindFullName(trial_name);
66
67 FieldTrialParameter<int> field_trial_param(/*key=*/"", *value_to_update);
68
69 ParseFieldTrial({&field_trial_param}, field_trial_str);
70 float field_trial_value = field_trial_param.Get();
71
Gustaf Ullberg398def62021-05-19 15:25:18 +020072 if (field_trial_value >= min && field_trial_value <= max &&
73 field_trial_value != *value_to_update) {
74 RTC_LOG(LS_INFO) << "Key " << trial_name
75 << " changing AEC3 parameter value from "
76 << *value_to_update << " to " << field_trial_value;
Per Åhgren80e52162020-04-06 14:57:52 +020077 *value_to_update = field_trial_value;
78 }
79}
80
81void FillSubFrameView(
82 AudioBuffer* frame,
83 size_t sub_frame_index,
84 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
85 RTC_DCHECK_GE(1, sub_frame_index);
86 RTC_DCHECK_LE(0, sub_frame_index);
87 RTC_DCHECK_EQ(frame->num_bands(), sub_frame_view->size());
88 RTC_DCHECK_EQ(frame->num_channels(), (*sub_frame_view)[0].size());
89 for (size_t band = 0; band < sub_frame_view->size(); ++band) {
90 for (size_t channel = 0; channel < (*sub_frame_view)[0].size(); ++channel) {
91 (*sub_frame_view)[band][channel] = rtc::ArrayView<float>(
92 &frame->split_bands(channel)[band][sub_frame_index * kSubFrameLength],
93 kSubFrameLength);
94 }
95 }
96}
97
98void FillSubFrameView(
99 std::vector<std::vector<std::vector<float>>>* frame,
100 size_t sub_frame_index,
101 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
102 RTC_DCHECK_GE(1, sub_frame_index);
103 RTC_DCHECK_EQ(frame->size(), sub_frame_view->size());
104 RTC_DCHECK_EQ((*frame)[0].size(), (*sub_frame_view)[0].size());
105 for (size_t band = 0; band < frame->size(); ++band) {
106 for (size_t channel = 0; channel < (*frame)[band].size(); ++channel) {
107 (*sub_frame_view)[band][channel] = rtc::ArrayView<float>(
108 &(*frame)[band][channel][sub_frame_index * kSubFrameLength],
109 kSubFrameLength);
110 }
111 }
112}
113
114void ProcessCaptureFrameContent(
115 AudioBuffer* linear_output,
116 AudioBuffer* capture,
117 bool level_change,
118 bool saturated_microphone_signal,
119 size_t sub_frame_index,
120 FrameBlocker* capture_blocker,
121 BlockFramer* linear_output_framer,
122 BlockFramer* output_framer,
123 BlockProcessor* block_processor,
124 std::vector<std::vector<std::vector<float>>>* linear_output_block,
125 std::vector<std::vector<rtc::ArrayView<float>>>*
126 linear_output_sub_frame_view,
127 std::vector<std::vector<std::vector<float>>>* capture_block,
128 std::vector<std::vector<rtc::ArrayView<float>>>* capture_sub_frame_view) {
129 FillSubFrameView(capture, sub_frame_index, capture_sub_frame_view);
130
131 if (linear_output) {
132 RTC_DCHECK(linear_output_framer);
133 RTC_DCHECK(linear_output_block);
134 RTC_DCHECK(linear_output_sub_frame_view);
135 FillSubFrameView(linear_output, sub_frame_index,
136 linear_output_sub_frame_view);
137 }
138
139 capture_blocker->InsertSubFrameAndExtractBlock(*capture_sub_frame_view,
140 capture_block);
141 block_processor->ProcessCapture(level_change, saturated_microphone_signal,
142 linear_output_block, capture_block);
143 output_framer->InsertBlockAndExtractSubFrame(*capture_block,
144 capture_sub_frame_view);
145
146 if (linear_output) {
147 RTC_DCHECK(linear_output_framer);
148 linear_output_framer->InsertBlockAndExtractSubFrame(
149 *linear_output_block, linear_output_sub_frame_view);
150 }
151}
152
153void ProcessRemainingCaptureFrameContent(
154 bool level_change,
155 bool saturated_microphone_signal,
156 FrameBlocker* capture_blocker,
157 BlockFramer* linear_output_framer,
158 BlockFramer* output_framer,
159 BlockProcessor* block_processor,
160 std::vector<std::vector<std::vector<float>>>* linear_output_block,
161 std::vector<std::vector<std::vector<float>>>* block) {
162 if (!capture_blocker->IsBlockAvailable()) {
163 return;
164 }
165
166 capture_blocker->ExtractBlock(block);
167 block_processor->ProcessCapture(level_change, saturated_microphone_signal,
168 linear_output_block, block);
169 output_framer->InsertBlock(*block);
170
171 if (linear_output_framer) {
172 RTC_DCHECK(linear_output_block);
173 linear_output_framer->InsertBlock(*linear_output_block);
174 }
175}
176
177void BufferRenderFrameContent(
178 std::vector<std::vector<std::vector<float>>>* render_frame,
179 size_t sub_frame_index,
180 FrameBlocker* render_blocker,
181 BlockProcessor* block_processor,
182 std::vector<std::vector<std::vector<float>>>* block,
183 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
184 FillSubFrameView(render_frame, sub_frame_index, sub_frame_view);
185 render_blocker->InsertSubFrameAndExtractBlock(*sub_frame_view, block);
186 block_processor->BufferRender(*block);
187}
188
189void BufferRemainingRenderFrameContent(
190 FrameBlocker* render_blocker,
191 BlockProcessor* block_processor,
192 std::vector<std::vector<std::vector<float>>>* block) {
193 if (!render_blocker->IsBlockAvailable()) {
194 return;
195 }
196 render_blocker->ExtractBlock(block);
197 block_processor->BufferRender(*block);
198}
199
200void CopyBufferIntoFrame(const AudioBuffer& buffer,
201 size_t num_bands,
202 size_t num_channels,
203 std::vector<std::vector<std::vector<float>>>* frame) {
204 RTC_DCHECK_EQ(num_bands, frame->size());
205 RTC_DCHECK_EQ(num_channels, (*frame)[0].size());
206 RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, (*frame)[0][0].size());
207 for (size_t band = 0; band < num_bands; ++band) {
208 for (size_t channel = 0; channel < num_channels; ++channel) {
209 rtc::ArrayView<const float> buffer_view(
210 &buffer.split_bands_const(channel)[band][0],
211 AudioBuffer::kSplitBandSize);
212 std::copy(buffer_view.begin(), buffer_view.end(),
213 (*frame)[band][channel].begin());
214 }
215 }
216}
217
218} // namespace
219
220// TODO(webrtc:5298): Move this to a separate file.
Per Åhgren251c7352018-03-28 16:31:57 +0200221EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) {
222 EchoCanceller3Config adjusted_cfg = config;
Gustaf Ullberg9249fbf2019-03-14 11:24:54 +0100223
Per Åhgrenf9f53312020-10-04 00:39:49 +0200224 if (field_trial::IsEnabled("WebRTC-Aec3AntiHowlingMinimizationKillSwitch")) {
225 adjusted_cfg.suppressor.high_bands_suppression
226 .anti_howling_activation_threshold = 25.f;
227 adjusted_cfg.suppressor.high_bands_suppression.anti_howling_gain = 0.01f;
228 }
229
Per Åhgrend8d09c32020-04-01 17:30:18 +0200230 if (field_trial::IsEnabled("WebRTC-Aec3UseShortConfigChangeDuration")) {
231 adjusted_cfg.filter.config_change_duration_blocks = 10;
232 }
233
234 if (field_trial::IsEnabled("WebRTC-Aec3UseZeroInitialStateDuration")) {
235 adjusted_cfg.filter.initial_state_seconds = 0.f;
236 } else if (field_trial::IsEnabled(
237 "WebRTC-Aec3UseDot1SecondsInitialStateDuration")) {
238 adjusted_cfg.filter.initial_state_seconds = .1f;
239 } else if (field_trial::IsEnabled(
240 "WebRTC-Aec3UseDot2SecondsInitialStateDuration")) {
241 adjusted_cfg.filter.initial_state_seconds = .2f;
242 } else if (field_trial::IsEnabled(
243 "WebRTC-Aec3UseDot3SecondsInitialStateDuration")) {
244 adjusted_cfg.filter.initial_state_seconds = .3f;
245 } else if (field_trial::IsEnabled(
246 "WebRTC-Aec3UseDot6SecondsInitialStateDuration")) {
247 adjusted_cfg.filter.initial_state_seconds = .6f;
248 } else if (field_trial::IsEnabled(
249 "WebRTC-Aec3UseDot9SecondsInitialStateDuration")) {
250 adjusted_cfg.filter.initial_state_seconds = .9f;
251 } else if (field_trial::IsEnabled(
252 "WebRTC-Aec3Use1Dot2SecondsInitialStateDuration")) {
253 adjusted_cfg.filter.initial_state_seconds = 1.2f;
254 } else if (field_trial::IsEnabled(
255 "WebRTC-Aec3Use1Dot6SecondsInitialStateDuration")) {
256 adjusted_cfg.filter.initial_state_seconds = 1.6f;
257 } else if (field_trial::IsEnabled(
258 "WebRTC-Aec3Use2Dot0SecondsInitialStateDuration")) {
259 adjusted_cfg.filter.initial_state_seconds = 2.0f;
260 }
261
Gustaf Ullberg09226fc2021-02-19 13:03:14 +0100262 if (field_trial::IsEnabled("WebRTC-Aec3HighPassFilterEchoReference")) {
263 adjusted_cfg.filter.high_pass_filter_echo_reference = true;
264 }
265
Per Åhgrend8d09c32020-04-01 17:30:18 +0200266 if (field_trial::IsEnabled("WebRTC-Aec3EchoSaturationDetectionKillSwitch")) {
267 adjusted_cfg.ep_strength.echo_can_saturate = false;
268 }
269
270 if (field_trial::IsEnabled("WebRTC-Aec3UseDot2ReverbDefaultLen")) {
271 adjusted_cfg.ep_strength.default_len = 0.2f;
272 } else if (field_trial::IsEnabled("WebRTC-Aec3UseDot3ReverbDefaultLen")) {
273 adjusted_cfg.ep_strength.default_len = 0.3f;
274 } else if (field_trial::IsEnabled("WebRTC-Aec3UseDot4ReverbDefaultLen")) {
275 adjusted_cfg.ep_strength.default_len = 0.4f;
276 } else if (field_trial::IsEnabled("WebRTC-Aec3UseDot5ReverbDefaultLen")) {
277 adjusted_cfg.ep_strength.default_len = 0.5f;
278 } else if (field_trial::IsEnabled("WebRTC-Aec3UseDot6ReverbDefaultLen")) {
279 adjusted_cfg.ep_strength.default_len = 0.6f;
280 } else if (field_trial::IsEnabled("WebRTC-Aec3UseDot7ReverbDefaultLen")) {
281 adjusted_cfg.ep_strength.default_len = 0.7f;
282 } else if (field_trial::IsEnabled("WebRTC-Aec3UseDot8ReverbDefaultLen")) {
283 adjusted_cfg.ep_strength.default_len = 0.8f;
284 }
285
Gustaf Ullberg9249fbf2019-03-14 11:24:54 +0100286 if (field_trial::IsEnabled("WebRTC-Aec3ShortHeadroomKillSwitch")) {
287 // Two blocks headroom.
288 adjusted_cfg.delay.delay_headroom_samples = kBlockSize * 2;
289 }
290
Per Åhgren8be669f2019-10-11 23:02:26 +0200291 if (field_trial::IsEnabled("WebRTC-Aec3ClampInstQualityToZeroKillSwitch")) {
292 adjusted_cfg.erle.clamp_quality_estimate_to_zero = false;
293 }
294
295 if (field_trial::IsEnabled("WebRTC-Aec3ClampInstQualityToOneKillSwitch")) {
296 adjusted_cfg.erle.clamp_quality_estimate_to_one = false;
297 }
298
Per Åhgrend8d09c32020-04-01 17:30:18 +0200299 if (field_trial::IsEnabled("WebRTC-Aec3OnsetDetectionKillSwitch")) {
300 adjusted_cfg.erle.onset_detection = false;
301 }
302
Per Åhgren6a05bb12019-12-03 11:24:59 +0100303 if (field_trial::IsEnabled(
304 "WebRTC-Aec3EnforceRenderDelayEstimationDownmixing")) {
305 adjusted_cfg.delay.render_alignment_mixing.downmix = true;
306 adjusted_cfg.delay.render_alignment_mixing.adaptive_selection = false;
307 }
308
309 if (field_trial::IsEnabled(
310 "WebRTC-Aec3EnforceCaptureDelayEstimationDownmixing")) {
311 adjusted_cfg.delay.capture_alignment_mixing.downmix = true;
312 adjusted_cfg.delay.capture_alignment_mixing.adaptive_selection = false;
313 }
314
315 if (field_trial::IsEnabled(
316 "WebRTC-Aec3EnforceCaptureDelayEstimationLeftRightPrioritization")) {
317 adjusted_cfg.delay.capture_alignment_mixing.prefer_first_two_channels =
318 true;
319 }
320
321 if (field_trial::IsEnabled(
322 "WebRTC-"
323 "Aec3RenderDelayEstimationLeftRightPrioritizationKillSwitch")) {
324 adjusted_cfg.delay.capture_alignment_mixing.prefer_first_two_channels =
325 false;
Per Åhgren9750e842019-11-28 17:19:27 +0100326 }
327
Per Åhgrend8d09c32020-04-01 17:30:18 +0200328 if (field_trial::IsEnabled("WebRTC-Aec3SensitiveDominantNearendActivation")) {
329 adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold = 0.5f;
330 } else if (field_trial::IsEnabled(
331 "WebRTC-Aec3VerySensitiveDominantNearendActivation")) {
332 adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold = 0.75f;
333 }
334
335 if (field_trial::IsEnabled("WebRTC-Aec3TransparentAntiHowlingGain")) {
336 adjusted_cfg.suppressor.high_bands_suppression.anti_howling_gain = 1.f;
337 }
338
339 if (field_trial::IsEnabled(
340 "WebRTC-Aec3EnforceMoreTransparentNormalSuppressorTuning")) {
341 adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_transparent = 0.4f;
342 adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_suppress = 0.5f;
343 }
344
345 if (field_trial::IsEnabled(
346 "WebRTC-Aec3EnforceMoreTransparentNearendSuppressorTuning")) {
347 adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_transparent = 1.29f;
348 adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_suppress = 1.3f;
349 }
350
351 if (field_trial::IsEnabled(
Per Åhgrend9c51142020-04-03 15:46:52 +0200352 "WebRTC-Aec3EnforceMoreTransparentNormalSuppressorHfTuning")) {
353 adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_transparent = 0.3f;
354 adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_suppress = 0.4f;
355 }
356
357 if (field_trial::IsEnabled(
358 "WebRTC-Aec3EnforceMoreTransparentNearendSuppressorHfTuning")) {
359 adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_transparent = 1.09f;
360 adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_suppress = 1.1f;
361 }
362
363 if (field_trial::IsEnabled(
Per Åhgrend8d09c32020-04-01 17:30:18 +0200364 "WebRTC-Aec3EnforceRapidlyAdjustingNormalSuppressorTunings")) {
365 adjusted_cfg.suppressor.normal_tuning.max_inc_factor = 2.5f;
366 }
367
368 if (field_trial::IsEnabled(
369 "WebRTC-Aec3EnforceRapidlyAdjustingNearendSuppressorTunings")) {
370 adjusted_cfg.suppressor.nearend_tuning.max_inc_factor = 2.5f;
371 }
372
373 if (field_trial::IsEnabled(
374 "WebRTC-Aec3EnforceSlowlyAdjustingNormalSuppressorTunings")) {
375 adjusted_cfg.suppressor.normal_tuning.max_dec_factor_lf = .2f;
376 }
377
378 if (field_trial::IsEnabled(
379 "WebRTC-Aec3EnforceSlowlyAdjustingNearendSuppressorTunings")) {
380 adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf = .2f;
381 }
382
Gustaf Ullberg7e4ad822020-10-22 14:36:37 +0200383 if (field_trial::IsEnabled("WebRTC-Aec3EnforceConservativeHfSuppression")) {
384 adjusted_cfg.suppressor.conservative_hf_suppression = true;
385 }
386
Per Åhgrend8d09c32020-04-01 17:30:18 +0200387 if (field_trial::IsEnabled("WebRTC-Aec3EnforceStationarityProperties")) {
388 adjusted_cfg.echo_audibility.use_stationarity_properties = true;
389 }
390
391 if (field_trial::IsEnabled(
392 "WebRTC-Aec3EnforceStationarityPropertiesAtInit")) {
393 adjusted_cfg.echo_audibility.use_stationarity_properties_at_init = true;
394 }
395
396 if (field_trial::IsEnabled("WebRTC-Aec3EnforceLowActiveRenderLimit")) {
397 adjusted_cfg.render_levels.active_render_limit = 50.f;
398 } else if (field_trial::IsEnabled(
399 "WebRTC-Aec3EnforceVeryLowActiveRenderLimit")) {
400 adjusted_cfg.render_levels.active_render_limit = 30.f;
401 }
402
Sam Zackrisson389bf0f2020-10-02 21:13:13 +0200403 if (field_trial::IsEnabled("WebRTC-Aec3NonlinearModeReverbKillSwitch")) {
404 adjusted_cfg.echo_model.model_reverb_in_nonlinear_mode = false;
405 }
406
Per Åhgren80e52162020-04-06 14:57:52 +0200407 // Field-trial based override for the whole suppressor tuning.
408 const std::string suppressor_tuning_override_trial_name =
409 field_trial::FindFullName("WebRTC-Aec3SuppressorTuningOverride");
410
411 FieldTrialParameter<double> nearend_tuning_mask_lf_enr_transparent(
412 "nearend_tuning_mask_lf_enr_transparent",
413 adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_transparent);
414 FieldTrialParameter<double> nearend_tuning_mask_lf_enr_suppress(
415 "nearend_tuning_mask_lf_enr_suppress",
416 adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_suppress);
417 FieldTrialParameter<double> nearend_tuning_mask_hf_enr_transparent(
418 "nearend_tuning_mask_hf_enr_transparent",
419 adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_transparent);
420 FieldTrialParameter<double> nearend_tuning_mask_hf_enr_suppress(
421 "nearend_tuning_mask_hf_enr_suppress",
422 adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_suppress);
423 FieldTrialParameter<double> nearend_tuning_max_inc_factor(
424 "nearend_tuning_max_inc_factor",
425 adjusted_cfg.suppressor.nearend_tuning.max_inc_factor);
426 FieldTrialParameter<double> nearend_tuning_max_dec_factor_lf(
427 "nearend_tuning_max_dec_factor_lf",
428 adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf);
429 FieldTrialParameter<double> normal_tuning_mask_lf_enr_transparent(
430 "normal_tuning_mask_lf_enr_transparent",
431 adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_transparent);
432 FieldTrialParameter<double> normal_tuning_mask_lf_enr_suppress(
433 "normal_tuning_mask_lf_enr_suppress",
434 adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_suppress);
435 FieldTrialParameter<double> normal_tuning_mask_hf_enr_transparent(
436 "normal_tuning_mask_hf_enr_transparent",
437 adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_transparent);
438 FieldTrialParameter<double> normal_tuning_mask_hf_enr_suppress(
439 "normal_tuning_mask_hf_enr_suppress",
440 adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_suppress);
441 FieldTrialParameter<double> normal_tuning_max_inc_factor(
442 "normal_tuning_max_inc_factor",
443 adjusted_cfg.suppressor.normal_tuning.max_inc_factor);
444 FieldTrialParameter<double> normal_tuning_max_dec_factor_lf(
445 "normal_tuning_max_dec_factor_lf",
446 adjusted_cfg.suppressor.normal_tuning.max_dec_factor_lf);
447 FieldTrialParameter<double> dominant_nearend_detection_enr_threshold(
448 "dominant_nearend_detection_enr_threshold",
449 adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold);
450 FieldTrialParameter<double> dominant_nearend_detection_enr_exit_threshold(
451 "dominant_nearend_detection_enr_exit_threshold",
452 adjusted_cfg.suppressor.dominant_nearend_detection.enr_exit_threshold);
453 FieldTrialParameter<double> dominant_nearend_detection_snr_threshold(
454 "dominant_nearend_detection_snr_threshold",
455 adjusted_cfg.suppressor.dominant_nearend_detection.snr_threshold);
456 FieldTrialParameter<int> dominant_nearend_detection_hold_duration(
457 "dominant_nearend_detection_hold_duration",
458 adjusted_cfg.suppressor.dominant_nearend_detection.hold_duration);
459 FieldTrialParameter<int> dominant_nearend_detection_trigger_threshold(
460 "dominant_nearend_detection_trigger_threshold",
461 adjusted_cfg.suppressor.dominant_nearend_detection.trigger_threshold);
462 FieldTrialParameter<double> ep_strength_default_len(
463 "ep_strength_default_len", adjusted_cfg.ep_strength.default_len);
464
465 ParseFieldTrial(
466 {&nearend_tuning_mask_lf_enr_transparent,
467 &nearend_tuning_mask_lf_enr_suppress,
468 &nearend_tuning_mask_hf_enr_transparent,
469 &nearend_tuning_mask_hf_enr_suppress, &nearend_tuning_max_inc_factor,
470 &nearend_tuning_max_dec_factor_lf,
471 &normal_tuning_mask_lf_enr_transparent,
472 &normal_tuning_mask_lf_enr_suppress,
473 &normal_tuning_mask_hf_enr_transparent,
474 &normal_tuning_mask_hf_enr_suppress, &normal_tuning_max_inc_factor,
475 &normal_tuning_max_dec_factor_lf,
476 &dominant_nearend_detection_enr_threshold,
477 &dominant_nearend_detection_enr_exit_threshold,
478 &dominant_nearend_detection_snr_threshold,
479 &dominant_nearend_detection_hold_duration,
480 &dominant_nearend_detection_trigger_threshold, &ep_strength_default_len},
481 suppressor_tuning_override_trial_name);
482
483 adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_transparent =
484 static_cast<float>(nearend_tuning_mask_lf_enr_transparent.Get());
485 adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_suppress =
486 static_cast<float>(nearend_tuning_mask_lf_enr_suppress.Get());
487 adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_transparent =
488 static_cast<float>(nearend_tuning_mask_hf_enr_transparent.Get());
489 adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_suppress =
490 static_cast<float>(nearend_tuning_mask_hf_enr_suppress.Get());
491 adjusted_cfg.suppressor.nearend_tuning.max_inc_factor =
492 static_cast<float>(nearend_tuning_max_inc_factor.Get());
493 adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf =
494 static_cast<float>(nearend_tuning_max_dec_factor_lf.Get());
495 adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_transparent =
496 static_cast<float>(normal_tuning_mask_lf_enr_transparent.Get());
497 adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_suppress =
498 static_cast<float>(normal_tuning_mask_lf_enr_suppress.Get());
499 adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_transparent =
500 static_cast<float>(normal_tuning_mask_hf_enr_transparent.Get());
501 adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_suppress =
502 static_cast<float>(normal_tuning_mask_hf_enr_suppress.Get());
503 adjusted_cfg.suppressor.normal_tuning.max_inc_factor =
504 static_cast<float>(normal_tuning_max_inc_factor.Get());
505 adjusted_cfg.suppressor.normal_tuning.max_dec_factor_lf =
506 static_cast<float>(normal_tuning_max_dec_factor_lf.Get());
507 adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold =
508 static_cast<float>(dominant_nearend_detection_enr_threshold.Get());
509 adjusted_cfg.suppressor.dominant_nearend_detection.enr_exit_threshold =
510 static_cast<float>(dominant_nearend_detection_enr_exit_threshold.Get());
511 adjusted_cfg.suppressor.dominant_nearend_detection.snr_threshold =
512 static_cast<float>(dominant_nearend_detection_snr_threshold.Get());
513 adjusted_cfg.suppressor.dominant_nearend_detection.hold_duration =
514 dominant_nearend_detection_hold_duration.Get();
515 adjusted_cfg.suppressor.dominant_nearend_detection.trigger_threshold =
516 dominant_nearend_detection_trigger_threshold.Get();
517 adjusted_cfg.ep_strength.default_len =
518 static_cast<float>(ep_strength_default_len.Get());
519
520 // Field trial-based overrides of individual suppressor parameters.
521 RetrieveFieldTrialValue(
522 "WebRTC-Aec3SuppressorNearendLfMaskTransparentOverride", 0.f, 10.f,
523 &adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_transparent);
524 RetrieveFieldTrialValue(
525 "WebRTC-Aec3SuppressorNearendLfMaskSuppressOverride", 0.f, 10.f,
526 &adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_suppress);
527 RetrieveFieldTrialValue(
528 "WebRTC-Aec3SuppressorNearendHfMaskTransparentOverride", 0.f, 10.f,
529 &adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_transparent);
530 RetrieveFieldTrialValue(
531 "WebRTC-Aec3SuppressorNearendHfMaskSuppressOverride", 0.f, 10.f,
532 &adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_suppress);
533 RetrieveFieldTrialValue(
534 "WebRTC-Aec3SuppressorNearendMaxIncFactorOverride", 0.f, 10.f,
535 &adjusted_cfg.suppressor.nearend_tuning.max_inc_factor);
536 RetrieveFieldTrialValue(
537 "WebRTC-Aec3SuppressorNearendMaxDecFactorLfOverride", 0.f, 10.f,
538 &adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf);
539
540 RetrieveFieldTrialValue(
541 "WebRTC-Aec3SuppressorNormalLfMaskTransparentOverride", 0.f, 10.f,
542 &adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_transparent);
543 RetrieveFieldTrialValue(
544 "WebRTC-Aec3SuppressorNormalLfMaskSuppressOverride", 0.f, 10.f,
545 &adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_suppress);
546 RetrieveFieldTrialValue(
547 "WebRTC-Aec3SuppressorNormalHfMaskTransparentOverride", 0.f, 10.f,
548 &adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_transparent);
549 RetrieveFieldTrialValue(
550 "WebRTC-Aec3SuppressorNormalHfMaskSuppressOverride", 0.f, 10.f,
551 &adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_suppress);
552 RetrieveFieldTrialValue(
553 "WebRTC-Aec3SuppressorNormalMaxIncFactorOverride", 0.f, 10.f,
554 &adjusted_cfg.suppressor.normal_tuning.max_inc_factor);
555 RetrieveFieldTrialValue(
556 "WebRTC-Aec3SuppressorNormalMaxDecFactorLfOverride", 0.f, 10.f,
557 &adjusted_cfg.suppressor.normal_tuning.max_dec_factor_lf);
558
559 RetrieveFieldTrialValue(
560 "WebRTC-Aec3SuppressorDominantNearendEnrThresholdOverride", 0.f, 100.f,
561 &adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold);
562 RetrieveFieldTrialValue(
563 "WebRTC-Aec3SuppressorDominantNearendEnrExitThresholdOverride", 0.f,
564 100.f,
565 &adjusted_cfg.suppressor.dominant_nearend_detection.enr_exit_threshold);
566 RetrieveFieldTrialValue(
567 "WebRTC-Aec3SuppressorDominantNearendSnrThresholdOverride", 0.f, 100.f,
568 &adjusted_cfg.suppressor.dominant_nearend_detection.snr_threshold);
569 RetrieveFieldTrialValue(
570 "WebRTC-Aec3SuppressorDominantNearendHoldDurationOverride", 0, 1000,
571 &adjusted_cfg.suppressor.dominant_nearend_detection.hold_duration);
572 RetrieveFieldTrialValue(
573 "WebRTC-Aec3SuppressorDominantNearendTriggerThresholdOverride", 0, 1000,
574 &adjusted_cfg.suppressor.dominant_nearend_detection.trigger_threshold);
575
576 RetrieveFieldTrialValue(
577 "WebRTC-Aec3SuppressorAntiHowlingGainOverride", 0.f, 10.f,
578 &adjusted_cfg.suppressor.high_bands_suppression.anti_howling_gain);
579
580 RetrieveFieldTrialValue("WebRTC-Aec3SuppressorEpStrengthDefaultLenOverride",
581 -1.f, 1.f, &adjusted_cfg.ep_strength.default_len);
582
Gustaf Ullbergaeb8ce82021-05-19 14:26:31 +0200583 // Field trial-based overrides of individual delay estimator parameters.
584 RetrieveFieldTrialValue("WebRTC-Aec3DelayEstimateSmoothingOverride", 0.f, 1.f,
585 &adjusted_cfg.delay.delay_estimate_smoothing);
586 RetrieveFieldTrialValue(
587 "WebRTC-Aec3DelayEstimateSmoothingDelayFoundOverride", 0.f, 1.f,
588 &adjusted_cfg.delay.delay_estimate_smoothing_delay_found);
Per Åhgren251c7352018-03-28 16:31:57 +0200589 return adjusted_cfg;
590}
591
peahd0263542017-01-03 04:20:34 -0800592class EchoCanceller3::RenderWriter {
593 public:
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000594 RenderWriter(ApmDataDumper* data_dumper,
Gustaf Ullberg09226fc2021-02-19 13:03:14 +0100595 const EchoCanceller3Config& config,
Per Åhgrence202a02019-09-02 17:01:19 +0200596 SwapQueue<std::vector<std::vector<std::vector<float>>>,
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000597 Aec3RenderQueueItemVerifier>* render_transfer_queue,
Per Åhgrence202a02019-09-02 17:01:19 +0200598 size_t num_bands,
599 size_t num_channels);
Niels Möllerde953292020-09-29 09:46:21 +0200600
601 RenderWriter() = delete;
602 RenderWriter(const RenderWriter&) = delete;
603 RenderWriter& operator=(const RenderWriter&) = delete;
604
peahd0263542017-01-03 04:20:34 -0800605 ~RenderWriter();
Per Åhgren0aefbf02019-08-23 21:29:17 +0200606 void Insert(const AudioBuffer& input);
peahd0263542017-01-03 04:20:34 -0800607
608 private:
609 ApmDataDumper* data_dumper_;
Per Åhgrence202a02019-09-02 17:01:19 +0200610 const size_t num_bands_;
611 const size_t num_channels_;
Gustaf Ullberg09226fc2021-02-19 13:03:14 +0100612 std::unique_ptr<HighPassFilter> high_pass_filter_;
Per Åhgrence202a02019-09-02 17:01:19 +0200613 std::vector<std::vector<std::vector<float>>> render_queue_input_frame_;
614 SwapQueue<std::vector<std::vector<std::vector<float>>>,
615 Aec3RenderQueueItemVerifier>* render_transfer_queue_;
peahd0263542017-01-03 04:20:34 -0800616};
617
618EchoCanceller3::RenderWriter::RenderWriter(
619 ApmDataDumper* data_dumper,
Gustaf Ullberg09226fc2021-02-19 13:03:14 +0100620 const EchoCanceller3Config& config,
Per Åhgrence202a02019-09-02 17:01:19 +0200621 SwapQueue<std::vector<std::vector<std::vector<float>>>,
622 Aec3RenderQueueItemVerifier>* render_transfer_queue,
623 size_t num_bands,
624 size_t num_channels)
peahd0263542017-01-03 04:20:34 -0800625 : data_dumper_(data_dumper),
peahd0263542017-01-03 04:20:34 -0800626 num_bands_(num_bands),
Per Åhgrence202a02019-09-02 17:01:19 +0200627 num_channels_(num_channels),
Per Åhgrence202a02019-09-02 17:01:19 +0200628 render_queue_input_frame_(
629 num_bands_,
630 std::vector<std::vector<float>>(
631 num_channels_,
632 std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
peahd0263542017-01-03 04:20:34 -0800633 render_transfer_queue_(render_transfer_queue) {
634 RTC_DCHECK(data_dumper);
Gustaf Ullberg09226fc2021-02-19 13:03:14 +0100635 if (config.filter.high_pass_filter_echo_reference) {
636 high_pass_filter_ = std::make_unique<HighPassFilter>(16000, num_channels);
637 }
peahd0263542017-01-03 04:20:34 -0800638}
639
640EchoCanceller3::RenderWriter::~RenderWriter() = default;
641
Per Åhgren0aefbf02019-08-23 21:29:17 +0200642void EchoCanceller3::RenderWriter::Insert(const AudioBuffer& input) {
Per Åhgrence202a02019-09-02 17:01:19 +0200643 RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, input.num_frames_per_band());
Per Åhgren0aefbf02019-08-23 21:29:17 +0200644 RTC_DCHECK_EQ(num_bands_, input.num_bands());
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200645 RTC_DCHECK_EQ(num_channels_, input.num_channels());
Gustaf Ullberg7d042782018-01-16 13:39:27 +0100646
647 // TODO(bugs.webrtc.org/8759) Temporary work-around.
Per Åhgrence202a02019-09-02 17:01:19 +0200648 if (num_bands_ != input.num_bands())
Gustaf Ullberg7d042782018-01-16 13:39:27 +0100649 return;
650
Per Åhgrence202a02019-09-02 17:01:19 +0200651 data_dumper_->DumpWav("aec3_render_input", AudioBuffer::kSplitBandSize,
652 &input.split_bands_const(0)[0][0], 16000, 1);
peahd0263542017-01-03 04:20:34 -0800653
Per Åhgrence202a02019-09-02 17:01:19 +0200654 CopyBufferIntoFrame(input, num_bands_, num_channels_,
peahcf02cf12017-04-05 14:18:07 -0700655 &render_queue_input_frame_);
Gustaf Ullberg09226fc2021-02-19 13:03:14 +0100656 if (high_pass_filter_) {
657 high_pass_filter_->Process(&render_queue_input_frame_[0]);
658 }
peahd0263542017-01-03 04:20:34 -0800659
peah925e9d72017-04-10 04:18:38 -0700660 static_cast<void>(render_transfer_queue_->Insert(&render_queue_input_frame_));
peahd0263542017-01-03 04:20:34 -0800661}
662
peahe0eae3c2016-12-14 01:16:23 -0800663int EchoCanceller3::instance_count_ = 0;
664
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200665EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config,
Per Åhgrence202a02019-09-02 17:01:19 +0200666 int sample_rate_hz,
667 size_t num_render_channels,
668 size_t num_capture_channels)
669 : EchoCanceller3(AdjustConfig(config),
670 sample_rate_hz,
671 num_render_channels,
672 num_capture_channels,
673 std::unique_ptr<BlockProcessor>(
674 BlockProcessor::Create(AdjustConfig(config),
675 sample_rate_hz,
676 num_render_channels,
677 num_capture_channels))) {}
Per Åhgren8ba58612017-12-01 23:01:44 +0100678EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config,
679 int sample_rate_hz,
Per Åhgrence202a02019-09-02 17:01:19 +0200680 size_t num_render_channels,
681 size_t num_capture_channels,
peahd0263542017-01-03 04:20:34 -0800682 std::unique_ptr<BlockProcessor> block_processor)
683 : data_dumper_(
684 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
Per Åhgren398689f2018-08-23 11:38:27 +0200685 config_(config),
peahd0263542017-01-03 04:20:34 -0800686 sample_rate_hz_(sample_rate_hz),
687 num_bands_(NumBandsForRate(sample_rate_hz_)),
Per Åhgrence202a02019-09-02 17:01:19 +0200688 num_render_channels_(num_render_channels),
689 num_capture_channels_(num_capture_channels),
690 output_framer_(num_bands_, num_capture_channels_),
691 capture_blocker_(num_bands_, num_capture_channels_),
692 render_blocker_(num_bands_, num_render_channels_),
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000693 render_transfer_queue_(
694 kRenderTransferQueueSizeFrames,
Per Åhgrence202a02019-09-02 17:01:19 +0200695 std::vector<std::vector<std::vector<float>>>(
Per Åhgrend112c752019-09-02 13:56:56 +0000696 num_bands_,
Per Åhgrence202a02019-09-02 17:01:19 +0200697 std::vector<std::vector<float>>(
698 num_render_channels_,
699 std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
700 Aec3RenderQueueItemVerifier(num_bands_,
701 num_render_channels_,
702 AudioBuffer::kSplitBandSize)),
Per Åhgrend112c752019-09-02 13:56:56 +0000703 block_processor_(std::move(block_processor)),
Per Åhgrence202a02019-09-02 17:01:19 +0200704 render_queue_output_frame_(
705 num_bands_,
706 std::vector<std::vector<float>>(
707 num_render_channels_,
708 std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
709 render_block_(
710 num_bands_,
711 std::vector<std::vector<float>>(num_render_channels_,
712 std::vector<float>(kBlockSize, 0.f))),
713 capture_block_(
714 num_bands_,
715 std::vector<std::vector<float>>(num_capture_channels_,
716 std::vector<float>(kBlockSize, 0.f))),
717 render_sub_frame_view_(
718 num_bands_,
719 std::vector<rtc::ArrayView<float>>(num_render_channels_)),
720 capture_sub_frame_view_(
721 num_bands_,
Per Åhgren260c7882020-01-28 15:38:41 +0100722 std::vector<rtc::ArrayView<float>>(num_capture_channels_)) {
peah21920892017-02-08 05:08:56 -0800723 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
724
Per Åhgren260c7882020-01-28 15:38:41 +0100725 if (config_.delay.fixed_capture_delay_samples > 0) {
726 block_delay_buffer_.reset(new BlockDelayBuffer(
727 num_capture_channels_, num_bands_, AudioBuffer::kSplitBandSize,
728 config_.delay.fixed_capture_delay_samples));
729 }
730
Gustaf Ullberg09226fc2021-02-19 13:03:14 +0100731 render_writer_.reset(new RenderWriter(data_dumper_.get(), config_,
Per Åhgrence202a02019-09-02 17:01:19 +0200732 &render_transfer_queue_, num_bands_,
733 num_render_channels_));
peahd0263542017-01-03 04:20:34 -0800734
735 RTC_DCHECK_EQ(num_bands_, std::max(sample_rate_hz_, 16000) / 16000);
736 RTC_DCHECK_GE(kMaxNumBands, num_bands_);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100737
738 if (config_.filter.export_linear_aec_output) {
739 linear_output_framer_.reset(new BlockFramer(1, num_capture_channels_));
740 linear_output_block_ =
741 std::make_unique<std::vector<std::vector<std::vector<float>>>>(
742 1, std::vector<std::vector<float>>(
743 num_capture_channels_, std::vector<float>(kBlockSize, 0.f)));
744 linear_output_sub_frame_view_ =
745 std::vector<std::vector<rtc::ArrayView<float>>>(
746 1, std::vector<rtc::ArrayView<float>>(num_capture_channels_));
747 }
Gustaf Ullberg398def62021-05-19 15:25:18 +0200748
749 RTC_LOG(LS_INFO) << "AEC3 created with sample rate: " << sample_rate_hz_
750 << " Hz, num render channels: " << num_render_channels_
751 << ", num capture channels: " << num_capture_channels_;
peahe0eae3c2016-12-14 01:16:23 -0800752}
753
754EchoCanceller3::~EchoCanceller3() = default;
755
Per Åhgren0aefbf02019-08-23 21:29:17 +0200756void EchoCanceller3::AnalyzeRender(const AudioBuffer& render) {
peahd0263542017-01-03 04:20:34 -0800757 RTC_DCHECK_RUNS_SERIALIZED(&render_race_checker_);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100758
Per Åhgrence202a02019-09-02 17:01:19 +0200759 RTC_DCHECK_EQ(render.num_channels(), num_render_channels_);
peahcf02cf12017-04-05 14:18:07 -0700760 data_dumper_->DumpRaw("aec3_call_order",
761 static_cast<int>(EchoCanceller3ApiCall::kRender));
762
peahd0263542017-01-03 04:20:34 -0800763 return render_writer_->Insert(render);
peahe0eae3c2016-12-14 01:16:23 -0800764}
765
Per Åhgren0aefbf02019-08-23 21:29:17 +0200766void EchoCanceller3::AnalyzeCapture(const AudioBuffer& capture) {
peahd0263542017-01-03 04:20:34 -0800767 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200768 data_dumper_->DumpWav("aec3_capture_analyze_input", capture.num_frames(),
769 capture.channels_const()[0], sample_rate_hz_, 1);
peahd0263542017-01-03 04:20:34 -0800770 saturated_microphone_signal_ = false;
Per Åhgrence202a02019-09-02 17:01:19 +0200771 for (size_t channel = 0; channel < capture.num_channels(); ++channel) {
peahd0263542017-01-03 04:20:34 -0800772 saturated_microphone_signal_ |=
Per Åhgren0aefbf02019-08-23 21:29:17 +0200773 DetectSaturation(rtc::ArrayView<const float>(
Per Åhgrence202a02019-09-02 17:01:19 +0200774 capture.channels_const()[channel], capture.num_frames()));
peahd0263542017-01-03 04:20:34 -0800775 if (saturated_microphone_signal_) {
776 break;
777 }
778 }
779}
peahe0eae3c2016-12-14 01:16:23 -0800780
peah69221db2017-01-27 03:28:19 -0800781void EchoCanceller3::ProcessCapture(AudioBuffer* capture, bool level_change) {
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100782 ProcessCapture(capture, nullptr, level_change);
783}
784
785void EchoCanceller3::ProcessCapture(AudioBuffer* capture,
786 AudioBuffer* linear_output,
787 bool level_change) {
peahd0263542017-01-03 04:20:34 -0800788 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
789 RTC_DCHECK(capture);
peahd0263542017-01-03 04:20:34 -0800790 RTC_DCHECK_EQ(num_bands_, capture->num_bands());
Per Åhgrence202a02019-09-02 17:01:19 +0200791 RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, capture->num_frames_per_band());
792 RTC_DCHECK_EQ(capture->num_channels(), num_capture_channels_);
peahcf02cf12017-04-05 14:18:07 -0700793 data_dumper_->DumpRaw("aec3_call_order",
794 static_cast<int>(EchoCanceller3ApiCall::kCapture));
peahd0263542017-01-03 04:20:34 -0800795
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100796 if (linear_output && !linear_output_framer_) {
797 RTC_LOG(LS_ERROR) << "Trying to retrieve the linear AEC output without "
798 "properly configuring AEC3.";
799 RTC_NOTREACHED();
800 }
801
Per Åhgren14f252a2018-11-27 18:02:56 +0100802 // Report capture call in the metrics and periodically update API call
803 // metrics.
804 api_call_metrics_.ReportCaptureCall();
805
Per Åhgren398689f2018-08-23 11:38:27 +0200806 // Optionally delay the capture signal.
807 if (config_.delay.fixed_capture_delay_samples > 0) {
Per Åhgren260c7882020-01-28 15:38:41 +0100808 RTC_DCHECK(block_delay_buffer_);
809 block_delay_buffer_->DelaySignal(capture);
Per Åhgren398689f2018-08-23 11:38:27 +0200810 }
811
Per Åhgrence202a02019-09-02 17:01:19 +0200812 rtc::ArrayView<float> capture_lower_band = rtc::ArrayView<float>(
813 &capture->split_bands(0)[0][0], AudioBuffer::kSplitBandSize);
peahd0263542017-01-03 04:20:34 -0800814
Per Åhgrence202a02019-09-02 17:01:19 +0200815 data_dumper_->DumpWav("aec3_capture_input", capture_lower_band, 16000, 1);
peahd0263542017-01-03 04:20:34 -0800816
peahcf02cf12017-04-05 14:18:07 -0700817 EmptyRenderQueue();
peahd0263542017-01-03 04:20:34 -0800818
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100819 ProcessCaptureFrameContent(linear_output, capture, level_change,
Per Åhgrence202a02019-09-02 17:01:19 +0200820 saturated_microphone_signal_, 0, &capture_blocker_,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100821 linear_output_framer_.get(), &output_framer_,
822 block_processor_.get(), linear_output_block_.get(),
823 &linear_output_sub_frame_view_, &capture_block_,
824 &capture_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800825
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100826 ProcessCaptureFrameContent(linear_output, capture, level_change,
Per Åhgrence202a02019-09-02 17:01:19 +0200827 saturated_microphone_signal_, 1, &capture_blocker_,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100828 linear_output_framer_.get(), &output_framer_,
829 block_processor_.get(), linear_output_block_.get(),
830 &linear_output_sub_frame_view_, &capture_block_,
831 &capture_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800832
833 ProcessRemainingCaptureFrameContent(
peah69221db2017-01-27 03:28:19 -0800834 level_change, saturated_microphone_signal_, &capture_blocker_,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100835 linear_output_framer_.get(), &output_framer_, block_processor_.get(),
836 linear_output_block_.get(), &capture_block_);
peahd0263542017-01-03 04:20:34 -0800837
Per Åhgrence202a02019-09-02 17:01:19 +0200838 data_dumper_->DumpWav("aec3_capture_output", AudioBuffer::kSplitBandSize,
839 &capture->split_bands(0)[0][0], 16000, 1);
peahe0eae3c2016-12-14 01:16:23 -0800840}
841
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100842EchoControl::Metrics EchoCanceller3::GetMetrics() const {
843 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
844 Metrics metrics;
845 block_processor_->GetMetrics(&metrics);
846 return metrics;
847}
848
Gustaf Ullberg3cb61042019-10-24 15:52:10 +0200849void EchoCanceller3::SetAudioBufferDelay(int delay_ms) {
Per Åhgrend0fa8202018-04-18 09:35:13 +0200850 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
851 block_processor_->SetAudioBufferDelay(delay_ms);
852}
853
Per Åhgren652ada52021-03-03 10:52:44 +0000854void EchoCanceller3::SetCaptureOutputUsage(bool capture_output_used) {
Per Åhgren8ee1ec82021-03-11 06:33:45 +0000855 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
856 block_processor_->SetCaptureOutputUsage(capture_output_used);
Per Åhgren652ada52021-03-03 10:52:44 +0000857}
858
Gustaf Ullberg8675eee2019-10-09 13:34:36 +0200859bool EchoCanceller3::ActiveProcessing() const {
860 return true;
861}
862
Per Åhgrenb2b58d82019-12-02 14:59:40 +0100863EchoCanceller3Config EchoCanceller3::CreateDefaultConfig(
864 size_t num_render_channels,
865 size_t num_capture_channels) {
866 EchoCanceller3Config cfg;
867 if (num_render_channels > 1) {
Per Åhgren9d661982020-03-20 11:26:48 +0100868 // Use shorter and more rapidly adapting coarse filter to compensate for
Per Åhgrenb2b58d82019-12-02 14:59:40 +0100869 // thge increased number of total filter parameters to adapt.
Per Åhgren9d661982020-03-20 11:26:48 +0100870 cfg.filter.coarse.length_blocks = 11;
871 cfg.filter.coarse.rate = 0.95f;
872 cfg.filter.coarse_initial.length_blocks = 11;
873 cfg.filter.coarse_initial.rate = 0.95f;
Per Åhgrenb2b58d82019-12-02 14:59:40 +0100874
875 // Use more concervative suppressor behavior for non-nearend speech.
876 cfg.suppressor.normal_tuning.max_dec_factor_lf = 0.35f;
877 cfg.suppressor.normal_tuning.max_inc_factor = 1.5f;
878 }
879 return cfg;
880}
881
peahcf02cf12017-04-05 14:18:07 -0700882void EchoCanceller3::EmptyRenderQueue() {
peahd0263542017-01-03 04:20:34 -0800883 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
peahd0263542017-01-03 04:20:34 -0800884 bool frame_to_buffer =
885 render_transfer_queue_.Remove(&render_queue_output_frame_);
886 while (frame_to_buffer) {
Per Åhgren14f252a2018-11-27 18:02:56 +0100887 // Report render call in the metrics.
888 api_call_metrics_.ReportRenderCall();
889
peahcf02cf12017-04-05 14:18:07 -0700890 BufferRenderFrameContent(&render_queue_output_frame_, 0, &render_blocker_,
Per Åhgrence202a02019-09-02 17:01:19 +0200891 block_processor_.get(), &render_block_,
892 &render_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800893
Per Åhgrence202a02019-09-02 17:01:19 +0200894 BufferRenderFrameContent(&render_queue_output_frame_, 1, &render_blocker_,
895 block_processor_.get(), &render_block_,
896 &render_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800897
peahcf02cf12017-04-05 14:18:07 -0700898 BufferRemainingRenderFrameContent(&render_blocker_, block_processor_.get(),
Per Åhgrence202a02019-09-02 17:01:19 +0200899 &render_block_);
peahd0263542017-01-03 04:20:34 -0800900
901 frame_to_buffer =
902 render_transfer_queue_.Remove(&render_queue_output_frame_);
903 }
peahd0263542017-01-03 04:20:34 -0800904}
peahe0eae3c2016-12-14 01:16:23 -0800905} // namespace webrtc