peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 1 | /* |
| 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 Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 11 | #include "modules/audio_processing/aec3/subtractor.h" |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 12 | |
| 13 | #include <algorithm> |
Yves Gerey | 988cc08 | 2018-10-23 12:03:01 +0200 | [diff] [blame] | 14 | #include <utility> |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 15 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 16 | #include "api/array_view.h" |
Per Åhgren | d4e6904 | 2019-09-05 15:55:58 +0200 | [diff] [blame] | 17 | #include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h" |
Yves Gerey | 988cc08 | 2018-10-23 12:03:01 +0200 | [diff] [blame] | 18 | #include "modules/audio_processing/aec3/fft_data.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 19 | #include "modules/audio_processing/logging/apm_data_dumper.h" |
| 20 | #include "rtc_base/checks.h" |
Karl Wiberg | e40468b | 2017-11-22 10:42:26 +0100 | [diff] [blame] | 21 | #include "rtc_base/numerics/safe_minmax.h" |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 22 | |
| 23 | namespace webrtc { |
| 24 | |
| 25 | namespace { |
| 26 | |
peah | 86afe9d | 2017-04-06 15:45:32 -0700 | [diff] [blame] | 27 | void PredictionError(const Aec3Fft& fft, |
| 28 | const FftData& S, |
| 29 | rtc::ArrayView<const float> y, |
| 30 | std::array<float, kBlockSize>* e, |
Per Åhgren | 45231be | 2019-05-16 14:43:57 +0200 | [diff] [blame] | 31 | std::array<float, kBlockSize>* s) { |
Per Åhgren | 7634c16 | 2017-12-18 15:45:49 +0100 | [diff] [blame] | 32 | std::array<float, kFftLength> tmp; |
| 33 | fft.Ifft(S, &tmp); |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 34 | constexpr float kScale = 1.0f / kFftLengthBy2; |
Per Åhgren | 7634c16 | 2017-12-18 15:45:49 +0100 | [diff] [blame] | 35 | std::transform(y.begin(), y.end(), tmp.begin() + kFftLengthBy2, e->begin(), |
| 36 | [&](float a, float b) { return a - b * kScale; }); |
peah | 2910357 | 2017-07-11 02:54:02 -0700 | [diff] [blame] | 37 | |
| 38 | if (s) { |
| 39 | for (size_t k = 0; k < s->size(); ++k) { |
Per Åhgren | 7634c16 | 2017-12-18 15:45:49 +0100 | [diff] [blame] | 40 | (*s)[k] = kScale * tmp[k + kFftLengthBy2]; |
peah | 2910357 | 2017-07-11 02:54:02 -0700 | [diff] [blame] | 41 | } |
Per Åhgren | 9845a67 | 2018-01-15 13:09:02 +0100 | [diff] [blame] | 42 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 43 | } |
Per Åhgren | ec22e3f | 2017-12-20 15:20:37 +0100 | [diff] [blame] | 44 | |
Per Åhgren | 7f5175a | 2018-07-25 16:30:54 +0200 | [diff] [blame] | 45 | void ScaleFilterOutput(rtc::ArrayView<const float> y, |
| 46 | float factor, |
| 47 | rtc::ArrayView<float> e, |
| 48 | rtc::ArrayView<float> s) { |
| 49 | RTC_DCHECK_EQ(y.size(), e.size()); |
| 50 | RTC_DCHECK_EQ(y.size(), s.size()); |
| 51 | for (size_t k = 0; k < y.size(); ++k) { |
| 52 | s[k] *= factor; |
| 53 | e[k] = y[k] - s[k]; |
| 54 | } |
| 55 | } |
| 56 | |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 57 | } // namespace |
| 58 | |
Per Åhgren | 09a718a | 2017-12-11 22:28:45 +0100 | [diff] [blame] | 59 | Subtractor::Subtractor(const EchoCanceller3Config& config, |
Per Åhgren | a33dc01 | 2019-09-03 23:59:52 +0200 | [diff] [blame] | 60 | size_t num_render_channels, |
| 61 | size_t num_capture_channels, |
Per Åhgren | 09a718a | 2017-12-11 22:28:45 +0100 | [diff] [blame] | 62 | ApmDataDumper* data_dumper, |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 63 | Aec3Optimization optimization) |
aleloi | 88b82b5 | 2017-02-23 06:27:03 -0800 | [diff] [blame] | 64 | : fft_(), |
| 65 | data_dumper_(data_dumper), |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 66 | optimization_(optimization), |
Per Åhgren | a98c807 | 2018-01-15 19:17:16 +0100 | [diff] [blame] | 67 | config_(config), |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 68 | num_capture_channels_(num_capture_channels), |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 69 | main_filters_(num_capture_channels_), |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 70 | shadow_filter_(num_capture_channels_), |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 71 | main_gains_(num_capture_channels_), |
| 72 | shadow_gains_(num_capture_channels_), |
| 73 | filter_misadjustment_estimators_(num_capture_channels_), |
| 74 | poor_shadow_filter_counters_(num_capture_channels_, 0), |
| 75 | main_frequency_responses_( |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 76 | num_capture_channels_, |
| 77 | std::vector<std::array<float, kFftLengthBy2Plus1>>( |
| 78 | std::max(config_.filter.main_initial.length_blocks, |
| 79 | config_.filter.main.length_blocks), |
| 80 | std::array<float, kFftLengthBy2Plus1>())), |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 81 | main_impulse_responses_( |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 82 | num_capture_channels_, |
| 83 | std::vector<float>(GetTimeDomainLength(std::max( |
| 84 | config_.filter.main_initial.length_blocks, |
| 85 | config_.filter.main.length_blocks)), |
| 86 | 0.f)) { |
| 87 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 88 | main_filters_[ch] = std::make_unique<AdaptiveFirFilter>( |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 89 | config_.filter.main.length_blocks, |
| 90 | config_.filter.main_initial.length_blocks, |
| 91 | config.filter.config_change_duration_blocks, num_render_channels, |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 92 | optimization, data_dumper_); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 93 | |
| 94 | shadow_filter_[ch] = std::make_unique<AdaptiveFirFilter>( |
| 95 | config_.filter.shadow.length_blocks, |
| 96 | config_.filter.shadow_initial.length_blocks, |
| 97 | config.filter.config_change_duration_blocks, num_render_channels, |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 98 | optimization, data_dumper_); |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 99 | main_gains_[ch] = std::make_unique<MainFilterUpdateGain>( |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 100 | config_.filter.main_initial, |
| 101 | config_.filter.config_change_duration_blocks); |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 102 | shadow_gains_[ch] = std::make_unique<ShadowFilterUpdateGain>( |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 103 | config_.filter.shadow_initial, |
| 104 | config.filter.config_change_duration_blocks); |
| 105 | } |
| 106 | |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 107 | RTC_DCHECK(data_dumper_); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 108 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 109 | for (auto& H2_k : main_frequency_responses_[ch]) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 110 | H2_k.fill(0.f); |
| 111 | } |
Per Åhgren | d4e6904 | 2019-09-05 15:55:58 +0200 | [diff] [blame] | 112 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 113 | } |
| 114 | |
peah | 2910357 | 2017-07-11 02:54:02 -0700 | [diff] [blame] | 115 | Subtractor::~Subtractor() = default; |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 116 | |
| 117 | void Subtractor::HandleEchoPathChange( |
| 118 | const EchoPathVariability& echo_path_variability) { |
Per Åhgren | 8ba5861 | 2017-12-01 23:01:44 +0100 | [diff] [blame] | 119 | const auto full_reset = [&]() { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 120 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 121 | main_filters_[ch]->HandleEchoPathChange(); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 122 | shadow_filter_[ch]->HandleEchoPathChange(); |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 123 | main_gains_[ch]->HandleEchoPathChange(echo_path_variability); |
| 124 | shadow_gains_[ch]->HandleEchoPathChange(); |
| 125 | main_gains_[ch]->SetConfig(config_.filter.main_initial, true); |
| 126 | shadow_gains_[ch]->SetConfig(config_.filter.shadow_initial, true); |
| 127 | main_filters_[ch]->SetSizePartitions( |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 128 | config_.filter.main_initial.length_blocks, true); |
| 129 | shadow_filter_[ch]->SetSizePartitions( |
| 130 | config_.filter.shadow_initial.length_blocks, true); |
| 131 | } |
Per Åhgren | 8ba5861 | 2017-12-01 23:01:44 +0100 | [diff] [blame] | 132 | }; |
| 133 | |
Per Åhgren | 88cf050 | 2018-07-16 17:08:41 +0200 | [diff] [blame] | 134 | if (echo_path_variability.delay_change != |
| 135 | EchoPathVariability::DelayAdjustment::kNone) { |
Per Åhgren | 8ba5861 | 2017-12-01 23:01:44 +0100 | [diff] [blame] | 136 | full_reset(); |
Per Åhgren | 88cf050 | 2018-07-16 17:08:41 +0200 | [diff] [blame] | 137 | } |
| 138 | |
Gustaf Ullberg | 68d6d44 | 2019-01-29 10:08:15 +0100 | [diff] [blame] | 139 | if (echo_path_variability.gain_change) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 140 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 141 | main_gains_[ch]->HandleEchoPathChange(echo_path_variability); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 142 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 143 | } |
| 144 | } |
| 145 | |
Per Åhgren | a98c807 | 2018-01-15 19:17:16 +0100 | [diff] [blame] | 146 | void Subtractor::ExitInitialState() { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 147 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 148 | main_gains_[ch]->SetConfig(config_.filter.main, false); |
| 149 | shadow_gains_[ch]->SetConfig(config_.filter.shadow, false); |
| 150 | main_filters_[ch]->SetSizePartitions(config_.filter.main.length_blocks, |
| 151 | false); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 152 | shadow_filter_[ch]->SetSizePartitions(config_.filter.shadow.length_blocks, |
| 153 | false); |
| 154 | } |
Per Åhgren | a98c807 | 2018-01-15 19:17:16 +0100 | [diff] [blame] | 155 | } |
| 156 | |
peah | cf02cf1 | 2017-04-05 14:18:07 -0700 | [diff] [blame] | 157 | void Subtractor::Process(const RenderBuffer& render_buffer, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 158 | const std::vector<std::vector<float>>& capture, |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 159 | const RenderSignalAnalyzer& render_signal_analyzer, |
peah | 86afe9d | 2017-04-06 15:45:32 -0700 | [diff] [blame] | 160 | const AecState& aec_state, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 161 | rtc::ArrayView<SubtractorOutput> outputs) { |
| 162 | RTC_DCHECK_EQ(num_capture_channels_, capture.size()); |
Per Åhgren | b5adc9e | 2018-01-15 13:20:20 +0100 | [diff] [blame] | 163 | |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 164 | // Compute the render powers. |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 165 | const bool same_filter_sizes = |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 166 | main_filters_[0]->SizePartitions() == shadow_filter_[0]->SizePartitions(); |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 167 | std::array<float, kFftLengthBy2Plus1> X2_main; |
| 168 | std::array<float, kFftLengthBy2Plus1> X2_shadow_data; |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 169 | auto& X2_shadow = same_filter_sizes ? X2_main : X2_shadow_data; |
| 170 | if (same_filter_sizes) { |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 171 | render_buffer.SpectralSum(main_filters_[0]->SizePartitions(), &X2_main); |
| 172 | } else if (main_filters_[0]->SizePartitions() > |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 173 | shadow_filter_[0]->SizePartitions()) { |
| 174 | render_buffer.SpectralSums(shadow_filter_[0]->SizePartitions(), |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 175 | main_filters_[0]->SizePartitions(), &X2_shadow, |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 176 | &X2_main); |
| 177 | } else { |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 178 | render_buffer.SpectralSums(main_filters_[0]->SizePartitions(), |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 179 | shadow_filter_[0]->SizePartitions(), &X2_main, |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 180 | &X2_shadow); |
| 181 | } |
| 182 | |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 183 | // Process all capture channels |
| 184 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
| 185 | RTC_DCHECK_EQ(kBlockSize, capture[ch].size()); |
| 186 | SubtractorOutput& output = outputs[ch]; |
| 187 | rtc::ArrayView<const float> y = capture[ch]; |
| 188 | FftData& E_main = output.E_main; |
| 189 | FftData E_shadow; |
| 190 | std::array<float, kBlockSize>& e_main = output.e_main; |
| 191 | std::array<float, kBlockSize>& e_shadow = output.e_shadow; |
| 192 | |
| 193 | FftData S; |
| 194 | FftData& G = S; |
| 195 | |
| 196 | // Form the outputs of the main and shadow filters. |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 197 | main_filters_[ch]->Filter(render_buffer, &S); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 198 | PredictionError(fft_, S, y, &e_main, &output.s_main); |
| 199 | |
| 200 | shadow_filter_[ch]->Filter(render_buffer, &S); |
| 201 | PredictionError(fft_, S, y, &e_shadow, &output.s_shadow); |
| 202 | |
| 203 | // Compute the signal powers in the subtractor output. |
| 204 | output.ComputeMetrics(y); |
| 205 | |
| 206 | // Adjust the filter if needed. |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 207 | bool main_filters_adjusted = false; |
| 208 | filter_misadjustment_estimators_[ch].Update(output); |
| 209 | if (filter_misadjustment_estimators_[ch].IsAdjustmentNeeded()) { |
| 210 | float scale = filter_misadjustment_estimators_[ch].GetMisadjustment(); |
| 211 | main_filters_[ch]->ScaleFilter(scale); |
| 212 | for (auto& h_k : main_impulse_responses_[ch]) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 213 | h_k *= scale; |
| 214 | } |
| 215 | ScaleFilterOutput(y, scale, e_main, output.s_main); |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 216 | filter_misadjustment_estimators_[ch].Reset(); |
| 217 | main_filters_adjusted = true; |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | // Compute the FFts of the main and shadow filter outputs. |
| 221 | fft_.ZeroPaddedFft(e_main, Aec3Fft::Window::kHanning, &E_main); |
| 222 | fft_.ZeroPaddedFft(e_shadow, Aec3Fft::Window::kHanning, &E_shadow); |
| 223 | |
| 224 | // Compute spectra for future use. |
| 225 | E_shadow.Spectrum(optimization_, output.E2_shadow); |
| 226 | E_main.Spectrum(optimization_, output.E2_main); |
| 227 | |
| 228 | // Update the main filter. |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 229 | if (!main_filters_adjusted) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 230 | std::array<float, kFftLengthBy2Plus1> erl; |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 231 | ComputeErl(optimization_, main_frequency_responses_[ch], erl); |
| 232 | main_gains_[ch]->Compute(X2_main, render_signal_analyzer, output, erl, |
| 233 | main_filters_[ch]->SizePartitions(), |
| 234 | aec_state.SaturatedCapture(), &G); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 235 | } else { |
| 236 | G.re.fill(0.f); |
| 237 | G.im.fill(0.f); |
| 238 | } |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 239 | main_filters_[ch]->Adapt(render_buffer, G, &main_impulse_responses_[ch]); |
| 240 | main_filters_[ch]->ComputeFrequencyResponse(&main_frequency_responses_[ch]); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 241 | |
| 242 | if (ch == 0) { |
| 243 | data_dumper_->DumpRaw("aec3_subtractor_G_main", G.re); |
| 244 | data_dumper_->DumpRaw("aec3_subtractor_G_main", G.im); |
| 245 | } |
| 246 | |
| 247 | // Update the shadow filter. |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 248 | poor_shadow_filter_counters_[ch] = |
| 249 | output.e2_main < output.e2_shadow ? poor_shadow_filter_counters_[ch] + 1 |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 250 | : 0; |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 251 | if (poor_shadow_filter_counters_[ch] < 5) { |
| 252 | shadow_gains_[ch]->Compute(X2_shadow, render_signal_analyzer, E_shadow, |
| 253 | shadow_filter_[ch]->SizePartitions(), |
| 254 | aec_state.SaturatedCapture(), &G); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 255 | } else { |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 256 | poor_shadow_filter_counters_[ch] = 0; |
| 257 | shadow_filter_[ch]->SetFilter(main_filters_[ch]->SizePartitions(), |
| 258 | main_filters_[ch]->GetFilter()); |
| 259 | shadow_gains_[ch]->Compute(X2_shadow, render_signal_analyzer, E_main, |
| 260 | shadow_filter_[ch]->SizePartitions(), |
| 261 | aec_state.SaturatedCapture(), &G); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 262 | } |
| 263 | |
| 264 | shadow_filter_[ch]->Adapt(render_buffer, G); |
| 265 | if (ch == 0) { |
| 266 | data_dumper_->DumpRaw("aec3_subtractor_G_shadow", G.re); |
| 267 | data_dumper_->DumpRaw("aec3_subtractor_G_shadow", G.im); |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 268 | filter_misadjustment_estimators_[ch].Dump(data_dumper_); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 269 | DumpFilters(); |
| 270 | } |
| 271 | |
| 272 | std::for_each(e_main.begin(), e_main.end(), |
| 273 | [](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); }); |
| 274 | |
| 275 | if (ch == 0) { |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 276 | data_dumper_->DumpWav("aec3_main_filters_output", kBlockSize, &e_main[0], |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 277 | 16000, 1); |
| 278 | data_dumper_->DumpWav("aec3_shadow_filter_output", kBlockSize, |
| 279 | &e_shadow[0], 16000, 1); |
| 280 | } |
Per Åhgren | 7f5175a | 2018-07-25 16:30:54 +0200 | [diff] [blame] | 281 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 282 | } |
| 283 | |
Per Åhgren | b20b937 | 2018-07-13 00:22:54 +0200 | [diff] [blame] | 284 | void Subtractor::FilterMisadjustmentEstimator::Update( |
Per Åhgren | e4db6a1 | 2018-07-26 15:32:24 +0200 | [diff] [blame] | 285 | const SubtractorOutput& output) { |
| 286 | e2_acum_ += output.e2_main; |
| 287 | y2_acum_ += output.y2; |
Jesús de Vicente Peña | 2e79d2b | 2018-06-29 16:35:08 +0200 | [diff] [blame] | 288 | if (++n_blocks_acum_ == n_blocks_) { |
| 289 | if (y2_acum_ > n_blocks_ * 200.f * 200.f * kBlockSize) { |
| 290 | float update = (e2_acum_ / y2_acum_); |
| 291 | if (e2_acum_ > n_blocks_ * 7500.f * 7500.f * kBlockSize) { |
Per Åhgren | e4db6a1 | 2018-07-26 15:32:24 +0200 | [diff] [blame] | 292 | // Duration equal to blockSizeMs * n_blocks_ * 4. |
| 293 | overhang_ = 4; |
Jesús de Vicente Peña | 2e79d2b | 2018-06-29 16:35:08 +0200 | [diff] [blame] | 294 | } else { |
| 295 | overhang_ = std::max(overhang_ - 1, 0); |
| 296 | } |
| 297 | |
| 298 | if ((update < inv_misadjustment_) || (overhang_ > 0)) { |
| 299 | inv_misadjustment_ += 0.1f * (update - inv_misadjustment_); |
| 300 | } |
| 301 | } |
| 302 | e2_acum_ = 0.f; |
| 303 | y2_acum_ = 0.f; |
| 304 | n_blocks_acum_ = 0; |
| 305 | } |
| 306 | } |
| 307 | |
| 308 | void Subtractor::FilterMisadjustmentEstimator::Reset() { |
| 309 | e2_acum_ = 0.f; |
| 310 | y2_acum_ = 0.f; |
| 311 | n_blocks_acum_ = 0; |
| 312 | inv_misadjustment_ = 0.f; |
| 313 | overhang_ = 0.f; |
| 314 | } |
| 315 | |
| 316 | void Subtractor::FilterMisadjustmentEstimator::Dump( |
| 317 | ApmDataDumper* data_dumper) const { |
| 318 | data_dumper->DumpRaw("aec3_inv_misadjustment_factor", inv_misadjustment_); |
| 319 | } |
| 320 | |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 321 | } // namespace webrtc |