blob: 2eae686752ddb2c75222042c173bb45ef04547d2 [file] [log] [blame]
peah522d71b2017-02-23 05:16:26 -08001/*
2 * Copyright (c) 2017 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_processing/aec3/subtractor.h"
peah522d71b2017-02-23 05:16:26 -080012
13#include <algorithm>
Yves Gerey988cc082018-10-23 12:03:01 +020014#include <utility>
peah522d71b2017-02-23 05:16:26 -080015
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "api/array_view.h"
Per Åhgrend4e69042019-09-05 15:55:58 +020017#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h"
Yves Gerey988cc082018-10-23 12:03:01 +020018#include "modules/audio_processing/aec3/fft_data.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/audio_processing/logging/apm_data_dumper.h"
20#include "rtc_base/checks.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010021#include "rtc_base/numerics/safe_minmax.h"
Gustaf Ullberg992a96f2020-12-08 13:03:55 +010022#include "system_wrappers/include/field_trial.h"
peah522d71b2017-02-23 05:16:26 -080023
24namespace webrtc {
25
26namespace {
27
Gustaf Ullberg992a96f2020-12-08 13:03:55 +010028bool UseCoarseFilterResetHangover() {
29 return !field_trial::IsEnabled(
30 "WebRTC-Aec3CoarseFilterResetHangoverKillSwitch");
31}
32
peah86afe9d2017-04-06 15:45:32 -070033void PredictionError(const Aec3Fft& fft,
34 const FftData& S,
35 rtc::ArrayView<const float> y,
36 std::array<float, kBlockSize>* e,
Per Åhgren45231be2019-05-16 14:43:57 +020037 std::array<float, kBlockSize>* s) {
Per Åhgren7634c162017-12-18 15:45:49 +010038 std::array<float, kFftLength> tmp;
39 fft.Ifft(S, &tmp);
peah522d71b2017-02-23 05:16:26 -080040 constexpr float kScale = 1.0f / kFftLengthBy2;
Per Åhgren7634c162017-12-18 15:45:49 +010041 std::transform(y.begin(), y.end(), tmp.begin() + kFftLengthBy2, e->begin(),
42 [&](float a, float b) { return a - b * kScale; });
peah29103572017-07-11 02:54:02 -070043
44 if (s) {
45 for (size_t k = 0; k < s->size(); ++k) {
Per Åhgren7634c162017-12-18 15:45:49 +010046 (*s)[k] = kScale * tmp[k + kFftLengthBy2];
peah29103572017-07-11 02:54:02 -070047 }
Per Åhgren9845a672018-01-15 13:09:02 +010048 }
peah522d71b2017-02-23 05:16:26 -080049}
Per Åhgrenec22e3f2017-12-20 15:20:37 +010050
Per Åhgren7f5175a2018-07-25 16:30:54 +020051void ScaleFilterOutput(rtc::ArrayView<const float> y,
52 float factor,
53 rtc::ArrayView<float> e,
54 rtc::ArrayView<float> s) {
55 RTC_DCHECK_EQ(y.size(), e.size());
56 RTC_DCHECK_EQ(y.size(), s.size());
57 for (size_t k = 0; k < y.size(); ++k) {
58 s[k] *= factor;
59 e[k] = y[k] - s[k];
60 }
61}
62
peah522d71b2017-02-23 05:16:26 -080063} // namespace
64
Per Åhgren09a718a2017-12-11 22:28:45 +010065Subtractor::Subtractor(const EchoCanceller3Config& config,
Per Åhgrena33dc012019-09-03 23:59:52 +020066 size_t num_render_channels,
67 size_t num_capture_channels,
Per Åhgren09a718a2017-12-11 22:28:45 +010068 ApmDataDumper* data_dumper,
peah522d71b2017-02-23 05:16:26 -080069 Aec3Optimization optimization)
aleloi88b82b52017-02-23 06:27:03 -080070 : fft_(),
71 data_dumper_(data_dumper),
peah522d71b2017-02-23 05:16:26 -080072 optimization_(optimization),
Per Åhgrena98c8072018-01-15 19:17:16 +010073 config_(config),
Per Åhgren7bdf0732019-09-25 14:53:30 +020074 num_capture_channels_(num_capture_channels),
Gustaf Ullberg992a96f2020-12-08 13:03:55 +010075 use_coarse_filter_reset_hangover_(UseCoarseFilterResetHangover()),
Per Åhgrenff045112020-03-20 11:20:39 +010076 refined_filters_(num_capture_channels_),
Per Åhgren9d661982020-03-20 11:26:48 +010077 coarse_filter_(num_capture_channels_),
Per Åhgrenff045112020-03-20 11:20:39 +010078 refined_gains_(num_capture_channels_),
Per Åhgren9d661982020-03-20 11:26:48 +010079 coarse_gains_(num_capture_channels_),
Per Åhgren119e2192019-10-18 08:50:50 +020080 filter_misadjustment_estimators_(num_capture_channels_),
Per Åhgren9d661982020-03-20 11:26:48 +010081 poor_coarse_filter_counters_(num_capture_channels_, 0),
Gustaf Ullberg992a96f2020-12-08 13:03:55 +010082 coarse_filter_reset_hangover_(num_capture_channels_, 0),
Per Åhgrenff045112020-03-20 11:20:39 +010083 refined_frequency_responses_(
Per Åhgren7bdf0732019-09-25 14:53:30 +020084 num_capture_channels_,
85 std::vector<std::array<float, kFftLengthBy2Plus1>>(
Per Åhgrenff045112020-03-20 11:20:39 +010086 std::max(config_.filter.refined_initial.length_blocks,
87 config_.filter.refined.length_blocks),
Per Åhgren7bdf0732019-09-25 14:53:30 +020088 std::array<float, kFftLengthBy2Plus1>())),
Per Åhgrenff045112020-03-20 11:20:39 +010089 refined_impulse_responses_(
Per Åhgren7bdf0732019-09-25 14:53:30 +020090 num_capture_channels_,
91 std::vector<float>(GetTimeDomainLength(std::max(
Per Åhgrenff045112020-03-20 11:20:39 +010092 config_.filter.refined_initial.length_blocks,
93 config_.filter.refined.length_blocks)),
Per Åhgren91a892f2021-05-07 23:28:42 +000094 0.f)),
95 coarse_impulse_responses_(0) {
96 // Set up the storing of coarse impulse responses if data dumping is
97 // available.
98 if (ApmDataDumper::IsAvailable()) {
99 coarse_impulse_responses_.resize(num_capture_channels_);
100 const size_t filter_size = GetTimeDomainLength(
101 std::max(config_.filter.coarse_initial.length_blocks,
102 config_.filter.coarse.length_blocks));
103 for (std::vector<float>& impulse_response : coarse_impulse_responses_) {
104 impulse_response.resize(filter_size, 0.f);
105 }
106 }
107
Per Åhgren7bdf0732019-09-25 14:53:30 +0200108 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +0100109 refined_filters_[ch] = std::make_unique<AdaptiveFirFilter>(
110 config_.filter.refined.length_blocks,
111 config_.filter.refined_initial.length_blocks,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200112 config.filter.config_change_duration_blocks, num_render_channels,
Per Åhgrenb441acf2019-10-05 09:07:24 +0200113 optimization, data_dumper_);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200114
Per Åhgren9d661982020-03-20 11:26:48 +0100115 coarse_filter_[ch] = std::make_unique<AdaptiveFirFilter>(
116 config_.filter.coarse.length_blocks,
117 config_.filter.coarse_initial.length_blocks,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200118 config.filter.config_change_duration_blocks, num_render_channels,
Per Åhgrenb441acf2019-10-05 09:07:24 +0200119 optimization, data_dumper_);
Per Åhgrenff045112020-03-20 11:20:39 +0100120 refined_gains_[ch] = std::make_unique<RefinedFilterUpdateGain>(
121 config_.filter.refined_initial,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200122 config_.filter.config_change_duration_blocks);
Per Åhgren9d661982020-03-20 11:26:48 +0100123 coarse_gains_[ch] = std::make_unique<CoarseFilterUpdateGain>(
124 config_.filter.coarse_initial,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200125 config.filter.config_change_duration_blocks);
126 }
127
peah522d71b2017-02-23 05:16:26 -0800128 RTC_DCHECK(data_dumper_);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200129 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +0100130 for (auto& H2_k : refined_frequency_responses_[ch]) {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200131 H2_k.fill(0.f);
132 }
Per Åhgrend4e69042019-09-05 15:55:58 +0200133 }
peah522d71b2017-02-23 05:16:26 -0800134}
135
peah29103572017-07-11 02:54:02 -0700136Subtractor::~Subtractor() = default;
peah522d71b2017-02-23 05:16:26 -0800137
138void Subtractor::HandleEchoPathChange(
139 const EchoPathVariability& echo_path_variability) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100140 const auto full_reset = [&]() {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200141 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +0100142 refined_filters_[ch]->HandleEchoPathChange();
Per Åhgren9d661982020-03-20 11:26:48 +0100143 coarse_filter_[ch]->HandleEchoPathChange();
Per Åhgrenff045112020-03-20 11:20:39 +0100144 refined_gains_[ch]->HandleEchoPathChange(echo_path_variability);
Per Åhgren9d661982020-03-20 11:26:48 +0100145 coarse_gains_[ch]->HandleEchoPathChange();
Per Åhgrenff045112020-03-20 11:20:39 +0100146 refined_gains_[ch]->SetConfig(config_.filter.refined_initial, true);
Per Åhgren9d661982020-03-20 11:26:48 +0100147 coarse_gains_[ch]->SetConfig(config_.filter.coarse_initial, true);
Per Åhgrenff045112020-03-20 11:20:39 +0100148 refined_filters_[ch]->SetSizePartitions(
149 config_.filter.refined_initial.length_blocks, true);
Per Åhgren9d661982020-03-20 11:26:48 +0100150 coarse_filter_[ch]->SetSizePartitions(
151 config_.filter.coarse_initial.length_blocks, true);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200152 }
Per Åhgren8ba58612017-12-01 23:01:44 +0100153 };
154
Per Åhgren88cf0502018-07-16 17:08:41 +0200155 if (echo_path_variability.delay_change !=
156 EchoPathVariability::DelayAdjustment::kNone) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100157 full_reset();
Per Åhgren88cf0502018-07-16 17:08:41 +0200158 }
159
Gustaf Ullberg68d6d442019-01-29 10:08:15 +0100160 if (echo_path_variability.gain_change) {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200161 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +0100162 refined_gains_[ch]->HandleEchoPathChange(echo_path_variability);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200163 }
peah522d71b2017-02-23 05:16:26 -0800164 }
165}
166
Per Åhgrena98c8072018-01-15 19:17:16 +0100167void Subtractor::ExitInitialState() {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200168 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +0100169 refined_gains_[ch]->SetConfig(config_.filter.refined, false);
Per Åhgren9d661982020-03-20 11:26:48 +0100170 coarse_gains_[ch]->SetConfig(config_.filter.coarse, false);
Per Åhgrenff045112020-03-20 11:20:39 +0100171 refined_filters_[ch]->SetSizePartitions(
172 config_.filter.refined.length_blocks, false);
Per Åhgren9d661982020-03-20 11:26:48 +0100173 coarse_filter_[ch]->SetSizePartitions(config_.filter.coarse.length_blocks,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200174 false);
175 }
Per Åhgrena98c8072018-01-15 19:17:16 +0100176}
177
peahcf02cf12017-04-05 14:18:07 -0700178void Subtractor::Process(const RenderBuffer& render_buffer,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200179 const std::vector<std::vector<float>>& capture,
peah522d71b2017-02-23 05:16:26 -0800180 const RenderSignalAnalyzer& render_signal_analyzer,
peah86afe9d2017-04-06 15:45:32 -0700181 const AecState& aec_state,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200182 rtc::ArrayView<SubtractorOutput> outputs) {
183 RTC_DCHECK_EQ(num_capture_channels_, capture.size());
Per Åhgrenb5adc9e2018-01-15 13:20:20 +0100184
Per Åhgrenee8ad5f2018-08-10 21:15:48 +0200185 // Compute the render powers.
Per Åhgrenff045112020-03-20 11:20:39 +0100186 const bool same_filter_sizes = refined_filters_[0]->SizePartitions() ==
Per Åhgren9d661982020-03-20 11:26:48 +0100187 coarse_filter_[0]->SizePartitions();
Per Åhgrenff045112020-03-20 11:20:39 +0100188 std::array<float, kFftLengthBy2Plus1> X2_refined;
Per Åhgren9d661982020-03-20 11:26:48 +0100189 std::array<float, kFftLengthBy2Plus1> X2_coarse_data;
190 auto& X2_coarse = same_filter_sizes ? X2_refined : X2_coarse_data;
Per Åhgrenb441acf2019-10-05 09:07:24 +0200191 if (same_filter_sizes) {
Per Åhgrenff045112020-03-20 11:20:39 +0100192 render_buffer.SpectralSum(refined_filters_[0]->SizePartitions(),
193 &X2_refined);
194 } else if (refined_filters_[0]->SizePartitions() >
Per Åhgren9d661982020-03-20 11:26:48 +0100195 coarse_filter_[0]->SizePartitions()) {
196 render_buffer.SpectralSums(coarse_filter_[0]->SizePartitions(),
Per Åhgrenff045112020-03-20 11:20:39 +0100197 refined_filters_[0]->SizePartitions(),
Per Åhgren9d661982020-03-20 11:26:48 +0100198 &X2_coarse, &X2_refined);
Per Åhgrenee8ad5f2018-08-10 21:15:48 +0200199 } else {
Per Åhgrenff045112020-03-20 11:20:39 +0100200 render_buffer.SpectralSums(refined_filters_[0]->SizePartitions(),
Per Åhgren9d661982020-03-20 11:26:48 +0100201 coarse_filter_[0]->SizePartitions(), &X2_refined,
202 &X2_coarse);
Per Åhgrenee8ad5f2018-08-10 21:15:48 +0200203 }
204
Per Åhgren7bdf0732019-09-25 14:53:30 +0200205 // Process all capture channels
206 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
207 RTC_DCHECK_EQ(kBlockSize, capture[ch].size());
208 SubtractorOutput& output = outputs[ch];
209 rtc::ArrayView<const float> y = capture[ch];
Per Åhgrenff045112020-03-20 11:20:39 +0100210 FftData& E_refined = output.E_refined;
Per Åhgren9d661982020-03-20 11:26:48 +0100211 FftData E_coarse;
Per Åhgrenff045112020-03-20 11:20:39 +0100212 std::array<float, kBlockSize>& e_refined = output.e_refined;
Per Åhgren9d661982020-03-20 11:26:48 +0100213 std::array<float, kBlockSize>& e_coarse = output.e_coarse;
Per Åhgren7bdf0732019-09-25 14:53:30 +0200214
215 FftData S;
216 FftData& G = S;
217
Per Åhgren9d661982020-03-20 11:26:48 +0100218 // Form the outputs of the refined and coarse filters.
Per Åhgrenff045112020-03-20 11:20:39 +0100219 refined_filters_[ch]->Filter(render_buffer, &S);
220 PredictionError(fft_, S, y, &e_refined, &output.s_refined);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200221
Per Åhgren9d661982020-03-20 11:26:48 +0100222 coarse_filter_[ch]->Filter(render_buffer, &S);
223 PredictionError(fft_, S, y, &e_coarse, &output.s_coarse);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200224
225 // Compute the signal powers in the subtractor output.
226 output.ComputeMetrics(y);
227
228 // Adjust the filter if needed.
Per Åhgrenff045112020-03-20 11:20:39 +0100229 bool refined_filters_adjusted = false;
Per Åhgren119e2192019-10-18 08:50:50 +0200230 filter_misadjustment_estimators_[ch].Update(output);
231 if (filter_misadjustment_estimators_[ch].IsAdjustmentNeeded()) {
232 float scale = filter_misadjustment_estimators_[ch].GetMisadjustment();
Per Åhgrenff045112020-03-20 11:20:39 +0100233 refined_filters_[ch]->ScaleFilter(scale);
234 for (auto& h_k : refined_impulse_responses_[ch]) {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200235 h_k *= scale;
236 }
Per Åhgrenff045112020-03-20 11:20:39 +0100237 ScaleFilterOutput(y, scale, e_refined, output.s_refined);
Per Åhgren119e2192019-10-18 08:50:50 +0200238 filter_misadjustment_estimators_[ch].Reset();
Per Åhgrenff045112020-03-20 11:20:39 +0100239 refined_filters_adjusted = true;
Per Åhgren7bdf0732019-09-25 14:53:30 +0200240 }
241
Per Åhgren9d661982020-03-20 11:26:48 +0100242 // Compute the FFts of the refined and coarse filter outputs.
Per Åhgrenff045112020-03-20 11:20:39 +0100243 fft_.ZeroPaddedFft(e_refined, Aec3Fft::Window::kHanning, &E_refined);
Per Åhgren9d661982020-03-20 11:26:48 +0100244 fft_.ZeroPaddedFft(e_coarse, Aec3Fft::Window::kHanning, &E_coarse);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200245
246 // Compute spectra for future use.
Per Åhgren9d661982020-03-20 11:26:48 +0100247 E_coarse.Spectrum(optimization_, output.E2_coarse);
Per Åhgrenff045112020-03-20 11:20:39 +0100248 E_refined.Spectrum(optimization_, output.E2_refined);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200249
Per Åhgrenff045112020-03-20 11:20:39 +0100250 // Update the refined filter.
251 if (!refined_filters_adjusted) {
Gustaf Ullberg992a96f2020-12-08 13:03:55 +0100252 // Do not allow the performance of the coarse filter to affect the
253 // adaptation speed of the refined filter just after the coarse filter has
254 // been reset.
255 const bool disallow_leakage_diverged =
256 coarse_filter_reset_hangover_[ch] > 0 &&
257 use_coarse_filter_reset_hangover_;
258
Per Åhgren7bdf0732019-09-25 14:53:30 +0200259 std::array<float, kFftLengthBy2Plus1> erl;
Per Åhgrenff045112020-03-20 11:20:39 +0100260 ComputeErl(optimization_, refined_frequency_responses_[ch], erl);
261 refined_gains_[ch]->Compute(X2_refined, render_signal_analyzer, output,
262 erl, refined_filters_[ch]->SizePartitions(),
Gustaf Ullberg992a96f2020-12-08 13:03:55 +0100263 aec_state.SaturatedCapture(),
264 disallow_leakage_diverged, &G);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200265 } else {
266 G.re.fill(0.f);
267 G.im.fill(0.f);
268 }
Per Åhgrenff045112020-03-20 11:20:39 +0100269 refined_filters_[ch]->Adapt(render_buffer, G,
270 &refined_impulse_responses_[ch]);
271 refined_filters_[ch]->ComputeFrequencyResponse(
272 &refined_frequency_responses_[ch]);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200273
274 if (ch == 0) {
Per Åhgrenff045112020-03-20 11:20:39 +0100275 data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.re);
276 data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.im);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200277 }
278
Per Åhgren9d661982020-03-20 11:26:48 +0100279 // Update the coarse filter.
280 poor_coarse_filter_counters_[ch] =
281 output.e2_refined < output.e2_coarse
282 ? poor_coarse_filter_counters_[ch] + 1
Per Åhgrenff045112020-03-20 11:20:39 +0100283 : 0;
Per Åhgren9d661982020-03-20 11:26:48 +0100284 if (poor_coarse_filter_counters_[ch] < 5) {
285 coarse_gains_[ch]->Compute(X2_coarse, render_signal_analyzer, E_coarse,
286 coarse_filter_[ch]->SizePartitions(),
Per Åhgren119e2192019-10-18 08:50:50 +0200287 aec_state.SaturatedCapture(), &G);
Gustaf Ullberg992a96f2020-12-08 13:03:55 +0100288 coarse_filter_reset_hangover_[ch] =
289 std::max(coarse_filter_reset_hangover_[ch] - 1, 0);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200290 } else {
Per Åhgren9d661982020-03-20 11:26:48 +0100291 poor_coarse_filter_counters_[ch] = 0;
292 coarse_filter_[ch]->SetFilter(refined_filters_[ch]->SizePartitions(),
Per Åhgrenff045112020-03-20 11:20:39 +0100293 refined_filters_[ch]->GetFilter());
Per Åhgren9d661982020-03-20 11:26:48 +0100294 coarse_gains_[ch]->Compute(X2_coarse, render_signal_analyzer, E_refined,
295 coarse_filter_[ch]->SizePartitions(),
Per Åhgren119e2192019-10-18 08:50:50 +0200296 aec_state.SaturatedCapture(), &G);
Gustaf Ullberg992a96f2020-12-08 13:03:55 +0100297 coarse_filter_reset_hangover_[ch] =
298 config_.filter.coarse_reset_hangover_blocks;
Per Åhgren7bdf0732019-09-25 14:53:30 +0200299 }
300
Per Åhgren91a892f2021-05-07 23:28:42 +0000301 if (ApmDataDumper::IsAvailable()) {
302 RTC_DCHECK_LT(ch, coarse_impulse_responses_.size());
303 coarse_filter_[ch]->Adapt(render_buffer, G,
304 &coarse_impulse_responses_[ch]);
305 } else {
306 coarse_filter_[ch]->Adapt(render_buffer, G);
307 }
308
Per Åhgren7bdf0732019-09-25 14:53:30 +0200309 if (ch == 0) {
Per Åhgren9d661982020-03-20 11:26:48 +0100310 data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.re);
311 data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.im);
Per Åhgren119e2192019-10-18 08:50:50 +0200312 filter_misadjustment_estimators_[ch].Dump(data_dumper_);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200313 DumpFilters();
314 }
315
Per Åhgrenff045112020-03-20 11:20:39 +0100316 std::for_each(e_refined.begin(), e_refined.end(),
Per Åhgren7bdf0732019-09-25 14:53:30 +0200317 [](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); });
318
319 if (ch == 0) {
Per Åhgrenff045112020-03-20 11:20:39 +0100320 data_dumper_->DumpWav("aec3_refined_filters_output", kBlockSize,
321 &e_refined[0], 16000, 1);
Per Åhgren9d661982020-03-20 11:26:48 +0100322 data_dumper_->DumpWav("aec3_coarse_filter_output", kBlockSize,
323 &e_coarse[0], 16000, 1);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200324 }
Per Åhgren7f5175a2018-07-25 16:30:54 +0200325 }
peah522d71b2017-02-23 05:16:26 -0800326}
327
Per Åhgrenb20b9372018-07-13 00:22:54 +0200328void Subtractor::FilterMisadjustmentEstimator::Update(
Per Åhgrene4db6a12018-07-26 15:32:24 +0200329 const SubtractorOutput& output) {
Per Åhgrenff045112020-03-20 11:20:39 +0100330 e2_acum_ += output.e2_refined;
Per Åhgrene4db6a12018-07-26 15:32:24 +0200331 y2_acum_ += output.y2;
Jesús de Vicente Peña2e79d2b2018-06-29 16:35:08 +0200332 if (++n_blocks_acum_ == n_blocks_) {
333 if (y2_acum_ > n_blocks_ * 200.f * 200.f * kBlockSize) {
334 float update = (e2_acum_ / y2_acum_);
335 if (e2_acum_ > n_blocks_ * 7500.f * 7500.f * kBlockSize) {
Per Åhgrene4db6a12018-07-26 15:32:24 +0200336 // Duration equal to blockSizeMs * n_blocks_ * 4.
337 overhang_ = 4;
Jesús de Vicente Peña2e79d2b2018-06-29 16:35:08 +0200338 } else {
339 overhang_ = std::max(overhang_ - 1, 0);
340 }
341
342 if ((update < inv_misadjustment_) || (overhang_ > 0)) {
343 inv_misadjustment_ += 0.1f * (update - inv_misadjustment_);
344 }
345 }
346 e2_acum_ = 0.f;
347 y2_acum_ = 0.f;
348 n_blocks_acum_ = 0;
349 }
350}
351
352void Subtractor::FilterMisadjustmentEstimator::Reset() {
353 e2_acum_ = 0.f;
354 y2_acum_ = 0.f;
355 n_blocks_acum_ = 0;
356 inv_misadjustment_ = 0.f;
357 overhang_ = 0.f;
358}
359
360void Subtractor::FilterMisadjustmentEstimator::Dump(
361 ApmDataDumper* data_dumper) const {
362 data_dumper->DumpRaw("aec3_inv_misadjustment_factor", inv_misadjustment_);
363}
364
peah522d71b2017-02-23 05:16:26 -0800365} // namespace webrtc