blob: d10e4ffc5245a824277ca43a528832246f396aa1 [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 Åhgren7bdf0732019-09-25 14:53:30 +020094 0.f)) {
95 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +010096 refined_filters_[ch] = std::make_unique<AdaptiveFirFilter>(
97 config_.filter.refined.length_blocks,
98 config_.filter.refined_initial.length_blocks,
Per Åhgren7bdf0732019-09-25 14:53:30 +020099 config.filter.config_change_duration_blocks, num_render_channels,
Per Åhgrenb441acf2019-10-05 09:07:24 +0200100 optimization, data_dumper_);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200101
Per Åhgren9d661982020-03-20 11:26:48 +0100102 coarse_filter_[ch] = std::make_unique<AdaptiveFirFilter>(
103 config_.filter.coarse.length_blocks,
104 config_.filter.coarse_initial.length_blocks,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200105 config.filter.config_change_duration_blocks, num_render_channels,
Per Åhgrenb441acf2019-10-05 09:07:24 +0200106 optimization, data_dumper_);
Per Åhgrenff045112020-03-20 11:20:39 +0100107 refined_gains_[ch] = std::make_unique<RefinedFilterUpdateGain>(
108 config_.filter.refined_initial,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200109 config_.filter.config_change_duration_blocks);
Per Åhgren9d661982020-03-20 11:26:48 +0100110 coarse_gains_[ch] = std::make_unique<CoarseFilterUpdateGain>(
111 config_.filter.coarse_initial,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200112 config.filter.config_change_duration_blocks);
113 }
114
peah522d71b2017-02-23 05:16:26 -0800115 RTC_DCHECK(data_dumper_);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200116 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +0100117 for (auto& H2_k : refined_frequency_responses_[ch]) {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200118 H2_k.fill(0.f);
119 }
Per Åhgrend4e69042019-09-05 15:55:58 +0200120 }
peah522d71b2017-02-23 05:16:26 -0800121}
122
peah29103572017-07-11 02:54:02 -0700123Subtractor::~Subtractor() = default;
peah522d71b2017-02-23 05:16:26 -0800124
125void Subtractor::HandleEchoPathChange(
126 const EchoPathVariability& echo_path_variability) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100127 const auto full_reset = [&]() {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200128 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +0100129 refined_filters_[ch]->HandleEchoPathChange();
Per Åhgren9d661982020-03-20 11:26:48 +0100130 coarse_filter_[ch]->HandleEchoPathChange();
Per Åhgrenff045112020-03-20 11:20:39 +0100131 refined_gains_[ch]->HandleEchoPathChange(echo_path_variability);
Per Åhgren9d661982020-03-20 11:26:48 +0100132 coarse_gains_[ch]->HandleEchoPathChange();
Per Åhgrenff045112020-03-20 11:20:39 +0100133 refined_gains_[ch]->SetConfig(config_.filter.refined_initial, true);
Per Åhgren9d661982020-03-20 11:26:48 +0100134 coarse_gains_[ch]->SetConfig(config_.filter.coarse_initial, true);
Per Åhgrenff045112020-03-20 11:20:39 +0100135 refined_filters_[ch]->SetSizePartitions(
136 config_.filter.refined_initial.length_blocks, true);
Per Åhgren9d661982020-03-20 11:26:48 +0100137 coarse_filter_[ch]->SetSizePartitions(
138 config_.filter.coarse_initial.length_blocks, true);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200139 }
Per Åhgren8ba58612017-12-01 23:01:44 +0100140 };
141
Per Åhgren88cf0502018-07-16 17:08:41 +0200142 if (echo_path_variability.delay_change !=
143 EchoPathVariability::DelayAdjustment::kNone) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100144 full_reset();
Per Åhgren88cf0502018-07-16 17:08:41 +0200145 }
146
Gustaf Ullberg68d6d442019-01-29 10:08:15 +0100147 if (echo_path_variability.gain_change) {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200148 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +0100149 refined_gains_[ch]->HandleEchoPathChange(echo_path_variability);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200150 }
peah522d71b2017-02-23 05:16:26 -0800151 }
152}
153
Per Åhgrena98c8072018-01-15 19:17:16 +0100154void Subtractor::ExitInitialState() {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200155 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
Per Åhgrenff045112020-03-20 11:20:39 +0100156 refined_gains_[ch]->SetConfig(config_.filter.refined, false);
Per Åhgren9d661982020-03-20 11:26:48 +0100157 coarse_gains_[ch]->SetConfig(config_.filter.coarse, false);
Per Åhgrenff045112020-03-20 11:20:39 +0100158 refined_filters_[ch]->SetSizePartitions(
159 config_.filter.refined.length_blocks, false);
Per Åhgren9d661982020-03-20 11:26:48 +0100160 coarse_filter_[ch]->SetSizePartitions(config_.filter.coarse.length_blocks,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200161 false);
162 }
Per Åhgrena98c8072018-01-15 19:17:16 +0100163}
164
peahcf02cf12017-04-05 14:18:07 -0700165void Subtractor::Process(const RenderBuffer& render_buffer,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200166 const std::vector<std::vector<float>>& capture,
peah522d71b2017-02-23 05:16:26 -0800167 const RenderSignalAnalyzer& render_signal_analyzer,
peah86afe9d2017-04-06 15:45:32 -0700168 const AecState& aec_state,
Per Åhgren7bdf0732019-09-25 14:53:30 +0200169 rtc::ArrayView<SubtractorOutput> outputs) {
170 RTC_DCHECK_EQ(num_capture_channels_, capture.size());
Per Åhgrenb5adc9e2018-01-15 13:20:20 +0100171
Per Åhgrenee8ad5f2018-08-10 21:15:48 +0200172 // Compute the render powers.
Per Åhgrenff045112020-03-20 11:20:39 +0100173 const bool same_filter_sizes = refined_filters_[0]->SizePartitions() ==
Per Åhgren9d661982020-03-20 11:26:48 +0100174 coarse_filter_[0]->SizePartitions();
Per Åhgrenff045112020-03-20 11:20:39 +0100175 std::array<float, kFftLengthBy2Plus1> X2_refined;
Per Åhgren9d661982020-03-20 11:26:48 +0100176 std::array<float, kFftLengthBy2Plus1> X2_coarse_data;
177 auto& X2_coarse = same_filter_sizes ? X2_refined : X2_coarse_data;
Per Åhgrenb441acf2019-10-05 09:07:24 +0200178 if (same_filter_sizes) {
Per Åhgrenff045112020-03-20 11:20:39 +0100179 render_buffer.SpectralSum(refined_filters_[0]->SizePartitions(),
180 &X2_refined);
181 } else if (refined_filters_[0]->SizePartitions() >
Per Åhgren9d661982020-03-20 11:26:48 +0100182 coarse_filter_[0]->SizePartitions()) {
183 render_buffer.SpectralSums(coarse_filter_[0]->SizePartitions(),
Per Åhgrenff045112020-03-20 11:20:39 +0100184 refined_filters_[0]->SizePartitions(),
Per Åhgren9d661982020-03-20 11:26:48 +0100185 &X2_coarse, &X2_refined);
Per Åhgrenee8ad5f2018-08-10 21:15:48 +0200186 } else {
Per Åhgrenff045112020-03-20 11:20:39 +0100187 render_buffer.SpectralSums(refined_filters_[0]->SizePartitions(),
Per Åhgren9d661982020-03-20 11:26:48 +0100188 coarse_filter_[0]->SizePartitions(), &X2_refined,
189 &X2_coarse);
Per Åhgrenee8ad5f2018-08-10 21:15:48 +0200190 }
191
Per Åhgren7bdf0732019-09-25 14:53:30 +0200192 // Process all capture channels
193 for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
194 RTC_DCHECK_EQ(kBlockSize, capture[ch].size());
195 SubtractorOutput& output = outputs[ch];
196 rtc::ArrayView<const float> y = capture[ch];
Per Åhgrenff045112020-03-20 11:20:39 +0100197 FftData& E_refined = output.E_refined;
Per Åhgren9d661982020-03-20 11:26:48 +0100198 FftData E_coarse;
Per Åhgrenff045112020-03-20 11:20:39 +0100199 std::array<float, kBlockSize>& e_refined = output.e_refined;
Per Åhgren9d661982020-03-20 11:26:48 +0100200 std::array<float, kBlockSize>& e_coarse = output.e_coarse;
Per Åhgren7bdf0732019-09-25 14:53:30 +0200201
202 FftData S;
203 FftData& G = S;
204
Per Åhgren9d661982020-03-20 11:26:48 +0100205 // Form the outputs of the refined and coarse filters.
Per Åhgrenff045112020-03-20 11:20:39 +0100206 refined_filters_[ch]->Filter(render_buffer, &S);
207 PredictionError(fft_, S, y, &e_refined, &output.s_refined);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200208
Per Åhgren9d661982020-03-20 11:26:48 +0100209 coarse_filter_[ch]->Filter(render_buffer, &S);
210 PredictionError(fft_, S, y, &e_coarse, &output.s_coarse);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200211
212 // Compute the signal powers in the subtractor output.
213 output.ComputeMetrics(y);
214
215 // Adjust the filter if needed.
Per Åhgrenff045112020-03-20 11:20:39 +0100216 bool refined_filters_adjusted = false;
Per Åhgren119e2192019-10-18 08:50:50 +0200217 filter_misadjustment_estimators_[ch].Update(output);
218 if (filter_misadjustment_estimators_[ch].IsAdjustmentNeeded()) {
219 float scale = filter_misadjustment_estimators_[ch].GetMisadjustment();
Per Åhgrenff045112020-03-20 11:20:39 +0100220 refined_filters_[ch]->ScaleFilter(scale);
221 for (auto& h_k : refined_impulse_responses_[ch]) {
Per Åhgren7bdf0732019-09-25 14:53:30 +0200222 h_k *= scale;
223 }
Per Åhgrenff045112020-03-20 11:20:39 +0100224 ScaleFilterOutput(y, scale, e_refined, output.s_refined);
Per Åhgren119e2192019-10-18 08:50:50 +0200225 filter_misadjustment_estimators_[ch].Reset();
Per Åhgrenff045112020-03-20 11:20:39 +0100226 refined_filters_adjusted = true;
Per Åhgren7bdf0732019-09-25 14:53:30 +0200227 }
228
Per Åhgren9d661982020-03-20 11:26:48 +0100229 // Compute the FFts of the refined and coarse filter outputs.
Per Åhgrenff045112020-03-20 11:20:39 +0100230 fft_.ZeroPaddedFft(e_refined, Aec3Fft::Window::kHanning, &E_refined);
Per Åhgren9d661982020-03-20 11:26:48 +0100231 fft_.ZeroPaddedFft(e_coarse, Aec3Fft::Window::kHanning, &E_coarse);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200232
233 // Compute spectra for future use.
Per Åhgren9d661982020-03-20 11:26:48 +0100234 E_coarse.Spectrum(optimization_, output.E2_coarse);
Per Åhgrenff045112020-03-20 11:20:39 +0100235 E_refined.Spectrum(optimization_, output.E2_refined);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200236
Per Åhgrenff045112020-03-20 11:20:39 +0100237 // Update the refined filter.
238 if (!refined_filters_adjusted) {
Gustaf Ullberg992a96f2020-12-08 13:03:55 +0100239 // Do not allow the performance of the coarse filter to affect the
240 // adaptation speed of the refined filter just after the coarse filter has
241 // been reset.
242 const bool disallow_leakage_diverged =
243 coarse_filter_reset_hangover_[ch] > 0 &&
244 use_coarse_filter_reset_hangover_;
245
Per Åhgren7bdf0732019-09-25 14:53:30 +0200246 std::array<float, kFftLengthBy2Plus1> erl;
Per Åhgrenff045112020-03-20 11:20:39 +0100247 ComputeErl(optimization_, refined_frequency_responses_[ch], erl);
248 refined_gains_[ch]->Compute(X2_refined, render_signal_analyzer, output,
249 erl, refined_filters_[ch]->SizePartitions(),
Gustaf Ullberg992a96f2020-12-08 13:03:55 +0100250 aec_state.SaturatedCapture(),
251 disallow_leakage_diverged, &G);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200252 } else {
253 G.re.fill(0.f);
254 G.im.fill(0.f);
255 }
Per Åhgrenff045112020-03-20 11:20:39 +0100256 refined_filters_[ch]->Adapt(render_buffer, G,
257 &refined_impulse_responses_[ch]);
258 refined_filters_[ch]->ComputeFrequencyResponse(
259 &refined_frequency_responses_[ch]);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200260
261 if (ch == 0) {
Per Åhgrenff045112020-03-20 11:20:39 +0100262 data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.re);
263 data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.im);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200264 }
265
Per Åhgren9d661982020-03-20 11:26:48 +0100266 // Update the coarse filter.
267 poor_coarse_filter_counters_[ch] =
268 output.e2_refined < output.e2_coarse
269 ? poor_coarse_filter_counters_[ch] + 1
Per Åhgrenff045112020-03-20 11:20:39 +0100270 : 0;
Per Åhgren9d661982020-03-20 11:26:48 +0100271 if (poor_coarse_filter_counters_[ch] < 5) {
272 coarse_gains_[ch]->Compute(X2_coarse, render_signal_analyzer, E_coarse,
273 coarse_filter_[ch]->SizePartitions(),
Per Åhgren119e2192019-10-18 08:50:50 +0200274 aec_state.SaturatedCapture(), &G);
Gustaf Ullberg992a96f2020-12-08 13:03:55 +0100275 coarse_filter_reset_hangover_[ch] =
276 std::max(coarse_filter_reset_hangover_[ch] - 1, 0);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200277 } else {
Per Åhgren9d661982020-03-20 11:26:48 +0100278 poor_coarse_filter_counters_[ch] = 0;
279 coarse_filter_[ch]->SetFilter(refined_filters_[ch]->SizePartitions(),
Per Åhgrenff045112020-03-20 11:20:39 +0100280 refined_filters_[ch]->GetFilter());
Per Åhgren9d661982020-03-20 11:26:48 +0100281 coarse_gains_[ch]->Compute(X2_coarse, render_signal_analyzer, E_refined,
282 coarse_filter_[ch]->SizePartitions(),
Per Åhgren119e2192019-10-18 08:50:50 +0200283 aec_state.SaturatedCapture(), &G);
Gustaf Ullberg992a96f2020-12-08 13:03:55 +0100284 coarse_filter_reset_hangover_[ch] =
285 config_.filter.coarse_reset_hangover_blocks;
Per Åhgren7bdf0732019-09-25 14:53:30 +0200286 }
287
Per Åhgren9d661982020-03-20 11:26:48 +0100288 coarse_filter_[ch]->Adapt(render_buffer, G);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200289 if (ch == 0) {
Per Åhgren9d661982020-03-20 11:26:48 +0100290 data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.re);
291 data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.im);
Per Åhgren119e2192019-10-18 08:50:50 +0200292 filter_misadjustment_estimators_[ch].Dump(data_dumper_);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200293 DumpFilters();
294 }
295
Per Åhgrenff045112020-03-20 11:20:39 +0100296 std::for_each(e_refined.begin(), e_refined.end(),
Per Åhgren7bdf0732019-09-25 14:53:30 +0200297 [](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); });
298
299 if (ch == 0) {
Per Åhgrenff045112020-03-20 11:20:39 +0100300 data_dumper_->DumpWav("aec3_refined_filters_output", kBlockSize,
301 &e_refined[0], 16000, 1);
Per Åhgren9d661982020-03-20 11:26:48 +0100302 data_dumper_->DumpWav("aec3_coarse_filter_output", kBlockSize,
303 &e_coarse[0], 16000, 1);
Per Åhgren7bdf0732019-09-25 14:53:30 +0200304 }
Per Åhgren7f5175a2018-07-25 16:30:54 +0200305 }
peah522d71b2017-02-23 05:16:26 -0800306}
307
Per Åhgrenb20b9372018-07-13 00:22:54 +0200308void Subtractor::FilterMisadjustmentEstimator::Update(
Per Åhgrene4db6a12018-07-26 15:32:24 +0200309 const SubtractorOutput& output) {
Per Åhgrenff045112020-03-20 11:20:39 +0100310 e2_acum_ += output.e2_refined;
Per Åhgrene4db6a12018-07-26 15:32:24 +0200311 y2_acum_ += output.y2;
Jesús de Vicente Peña2e79d2b2018-06-29 16:35:08 +0200312 if (++n_blocks_acum_ == n_blocks_) {
313 if (y2_acum_ > n_blocks_ * 200.f * 200.f * kBlockSize) {
314 float update = (e2_acum_ / y2_acum_);
315 if (e2_acum_ > n_blocks_ * 7500.f * 7500.f * kBlockSize) {
Per Åhgrene4db6a12018-07-26 15:32:24 +0200316 // Duration equal to blockSizeMs * n_blocks_ * 4.
317 overhang_ = 4;
Jesús de Vicente Peña2e79d2b2018-06-29 16:35:08 +0200318 } else {
319 overhang_ = std::max(overhang_ - 1, 0);
320 }
321
322 if ((update < inv_misadjustment_) || (overhang_ > 0)) {
323 inv_misadjustment_ += 0.1f * (update - inv_misadjustment_);
324 }
325 }
326 e2_acum_ = 0.f;
327 y2_acum_ = 0.f;
328 n_blocks_acum_ = 0;
329 }
330}
331
332void Subtractor::FilterMisadjustmentEstimator::Reset() {
333 e2_acum_ = 0.f;
334 y2_acum_ = 0.f;
335 n_blocks_acum_ = 0;
336 inv_misadjustment_ = 0.f;
337 overhang_ = 0.f;
338}
339
340void Subtractor::FilterMisadjustmentEstimator::Dump(
341 ApmDataDumper* data_dumper) const {
342 data_dumper->DumpRaw("aec3_inv_misadjustment_factor", inv_misadjustment_);
343}
344
peah522d71b2017-02-23 05:16:26 -0800345} // namespace webrtc