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" |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame] | 22 | #include "system_wrappers/include/field_trial.h" |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 23 | |
| 24 | namespace webrtc { |
| 25 | |
| 26 | namespace { |
| 27 | |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame] | 28 | bool UseCoarseFilterResetHangover() { |
| 29 | return !field_trial::IsEnabled( |
| 30 | "WebRTC-Aec3CoarseFilterResetHangoverKillSwitch"); |
| 31 | } |
| 32 | |
peah | 86afe9d | 2017-04-06 15:45:32 -0700 | [diff] [blame] | 33 | void PredictionError(const Aec3Fft& fft, |
| 34 | const FftData& S, |
| 35 | rtc::ArrayView<const float> y, |
| 36 | std::array<float, kBlockSize>* e, |
Per Åhgren | 45231be | 2019-05-16 14:43:57 +0200 | [diff] [blame] | 37 | std::array<float, kBlockSize>* s) { |
Per Åhgren | 7634c16 | 2017-12-18 15:45:49 +0100 | [diff] [blame] | 38 | std::array<float, kFftLength> tmp; |
| 39 | fft.Ifft(S, &tmp); |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 40 | constexpr float kScale = 1.0f / kFftLengthBy2; |
Per Åhgren | 7634c16 | 2017-12-18 15:45:49 +0100 | [diff] [blame] | 41 | std::transform(y.begin(), y.end(), tmp.begin() + kFftLengthBy2, e->begin(), |
| 42 | [&](float a, float b) { return a - b * kScale; }); |
peah | 2910357 | 2017-07-11 02:54:02 -0700 | [diff] [blame] | 43 | |
| 44 | if (s) { |
| 45 | for (size_t k = 0; k < s->size(); ++k) { |
Per Åhgren | 7634c16 | 2017-12-18 15:45:49 +0100 | [diff] [blame] | 46 | (*s)[k] = kScale * tmp[k + kFftLengthBy2]; |
peah | 2910357 | 2017-07-11 02:54:02 -0700 | [diff] [blame] | 47 | } |
Per Åhgren | 9845a67 | 2018-01-15 13:09:02 +0100 | [diff] [blame] | 48 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 49 | } |
Per Åhgren | ec22e3f | 2017-12-20 15:20:37 +0100 | [diff] [blame] | 50 | |
Per Åhgren | 7f5175a | 2018-07-25 16:30:54 +0200 | [diff] [blame] | 51 | void 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 | |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 63 | } // namespace |
| 64 | |
Per Åhgren | 09a718a | 2017-12-11 22:28:45 +0100 | [diff] [blame] | 65 | Subtractor::Subtractor(const EchoCanceller3Config& config, |
Per Åhgren | a33dc01 | 2019-09-03 23:59:52 +0200 | [diff] [blame] | 66 | size_t num_render_channels, |
| 67 | size_t num_capture_channels, |
Per Åhgren | 09a718a | 2017-12-11 22:28:45 +0100 | [diff] [blame] | 68 | ApmDataDumper* data_dumper, |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 69 | Aec3Optimization optimization) |
aleloi | 88b82b5 | 2017-02-23 06:27:03 -0800 | [diff] [blame] | 70 | : fft_(), |
| 71 | data_dumper_(data_dumper), |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 72 | optimization_(optimization), |
Per Åhgren | a98c807 | 2018-01-15 19:17:16 +0100 | [diff] [blame] | 73 | config_(config), |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 74 | num_capture_channels_(num_capture_channels), |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame] | 75 | use_coarse_filter_reset_hangover_(UseCoarseFilterResetHangover()), |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 76 | refined_filters_(num_capture_channels_), |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 77 | coarse_filter_(num_capture_channels_), |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 78 | refined_gains_(num_capture_channels_), |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 79 | coarse_gains_(num_capture_channels_), |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 80 | filter_misadjustment_estimators_(num_capture_channels_), |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 81 | poor_coarse_filter_counters_(num_capture_channels_, 0), |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame] | 82 | coarse_filter_reset_hangover_(num_capture_channels_, 0), |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 83 | refined_frequency_responses_( |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 84 | num_capture_channels_, |
| 85 | std::vector<std::array<float, kFftLengthBy2Plus1>>( |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 86 | std::max(config_.filter.refined_initial.length_blocks, |
| 87 | config_.filter.refined.length_blocks), |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 88 | std::array<float, kFftLengthBy2Plus1>())), |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 89 | refined_impulse_responses_( |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 90 | num_capture_channels_, |
| 91 | std::vector<float>(GetTimeDomainLength(std::max( |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 92 | config_.filter.refined_initial.length_blocks, |
| 93 | config_.filter.refined.length_blocks)), |
Per Åhgren | 91a892f | 2021-05-07 23:28:42 +0000 | [diff] [blame] | 94 | 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 Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 108 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 109 | refined_filters_[ch] = std::make_unique<AdaptiveFirFilter>( |
| 110 | config_.filter.refined.length_blocks, |
| 111 | config_.filter.refined_initial.length_blocks, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 112 | config.filter.config_change_duration_blocks, num_render_channels, |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 113 | optimization, data_dumper_); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 114 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 115 | coarse_filter_[ch] = std::make_unique<AdaptiveFirFilter>( |
| 116 | config_.filter.coarse.length_blocks, |
| 117 | config_.filter.coarse_initial.length_blocks, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 118 | config.filter.config_change_duration_blocks, num_render_channels, |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 119 | optimization, data_dumper_); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 120 | refined_gains_[ch] = std::make_unique<RefinedFilterUpdateGain>( |
| 121 | config_.filter.refined_initial, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 122 | config_.filter.config_change_duration_blocks); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 123 | coarse_gains_[ch] = std::make_unique<CoarseFilterUpdateGain>( |
| 124 | config_.filter.coarse_initial, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 125 | config.filter.config_change_duration_blocks); |
| 126 | } |
| 127 | |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 128 | RTC_DCHECK(data_dumper_); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 129 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 130 | for (auto& H2_k : refined_frequency_responses_[ch]) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 131 | H2_k.fill(0.f); |
| 132 | } |
Per Åhgren | d4e6904 | 2019-09-05 15:55:58 +0200 | [diff] [blame] | 133 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 134 | } |
| 135 | |
peah | 2910357 | 2017-07-11 02:54:02 -0700 | [diff] [blame] | 136 | Subtractor::~Subtractor() = default; |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 137 | |
| 138 | void Subtractor::HandleEchoPathChange( |
| 139 | const EchoPathVariability& echo_path_variability) { |
Per Åhgren | 8ba5861 | 2017-12-01 23:01:44 +0100 | [diff] [blame] | 140 | const auto full_reset = [&]() { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 141 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 142 | refined_filters_[ch]->HandleEchoPathChange(); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 143 | coarse_filter_[ch]->HandleEchoPathChange(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 144 | refined_gains_[ch]->HandleEchoPathChange(echo_path_variability); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 145 | coarse_gains_[ch]->HandleEchoPathChange(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 146 | refined_gains_[ch]->SetConfig(config_.filter.refined_initial, true); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 147 | coarse_gains_[ch]->SetConfig(config_.filter.coarse_initial, true); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 148 | refined_filters_[ch]->SetSizePartitions( |
| 149 | config_.filter.refined_initial.length_blocks, true); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 150 | coarse_filter_[ch]->SetSizePartitions( |
| 151 | config_.filter.coarse_initial.length_blocks, true); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 152 | } |
Per Åhgren | 8ba5861 | 2017-12-01 23:01:44 +0100 | [diff] [blame] | 153 | }; |
| 154 | |
Per Åhgren | 88cf050 | 2018-07-16 17:08:41 +0200 | [diff] [blame] | 155 | if (echo_path_variability.delay_change != |
| 156 | EchoPathVariability::DelayAdjustment::kNone) { |
Per Åhgren | 8ba5861 | 2017-12-01 23:01:44 +0100 | [diff] [blame] | 157 | full_reset(); |
Per Åhgren | 88cf050 | 2018-07-16 17:08:41 +0200 | [diff] [blame] | 158 | } |
| 159 | |
Gustaf Ullberg | 68d6d44 | 2019-01-29 10:08:15 +0100 | [diff] [blame] | 160 | if (echo_path_variability.gain_change) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 161 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 162 | refined_gains_[ch]->HandleEchoPathChange(echo_path_variability); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 163 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 164 | } |
| 165 | } |
| 166 | |
Per Åhgren | a98c807 | 2018-01-15 19:17:16 +0100 | [diff] [blame] | 167 | void Subtractor::ExitInitialState() { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 168 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 169 | refined_gains_[ch]->SetConfig(config_.filter.refined, false); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 170 | coarse_gains_[ch]->SetConfig(config_.filter.coarse, false); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 171 | refined_filters_[ch]->SetSizePartitions( |
| 172 | config_.filter.refined.length_blocks, false); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 173 | coarse_filter_[ch]->SetSizePartitions(config_.filter.coarse.length_blocks, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 174 | false); |
| 175 | } |
Per Åhgren | a98c807 | 2018-01-15 19:17:16 +0100 | [diff] [blame] | 176 | } |
| 177 | |
peah | cf02cf1 | 2017-04-05 14:18:07 -0700 | [diff] [blame] | 178 | void Subtractor::Process(const RenderBuffer& render_buffer, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 179 | const std::vector<std::vector<float>>& capture, |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 180 | const RenderSignalAnalyzer& render_signal_analyzer, |
peah | 86afe9d | 2017-04-06 15:45:32 -0700 | [diff] [blame] | 181 | const AecState& aec_state, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 182 | rtc::ArrayView<SubtractorOutput> outputs) { |
| 183 | RTC_DCHECK_EQ(num_capture_channels_, capture.size()); |
Per Åhgren | b5adc9e | 2018-01-15 13:20:20 +0100 | [diff] [blame] | 184 | |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 185 | // Compute the render powers. |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 186 | const bool same_filter_sizes = refined_filters_[0]->SizePartitions() == |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 187 | coarse_filter_[0]->SizePartitions(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 188 | std::array<float, kFftLengthBy2Plus1> X2_refined; |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 189 | std::array<float, kFftLengthBy2Plus1> X2_coarse_data; |
| 190 | auto& X2_coarse = same_filter_sizes ? X2_refined : X2_coarse_data; |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 191 | if (same_filter_sizes) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 192 | render_buffer.SpectralSum(refined_filters_[0]->SizePartitions(), |
| 193 | &X2_refined); |
| 194 | } else if (refined_filters_[0]->SizePartitions() > |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 195 | coarse_filter_[0]->SizePartitions()) { |
| 196 | render_buffer.SpectralSums(coarse_filter_[0]->SizePartitions(), |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 197 | refined_filters_[0]->SizePartitions(), |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 198 | &X2_coarse, &X2_refined); |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 199 | } else { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 200 | render_buffer.SpectralSums(refined_filters_[0]->SizePartitions(), |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 201 | coarse_filter_[0]->SizePartitions(), &X2_refined, |
| 202 | &X2_coarse); |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 203 | } |
| 204 | |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 205 | // 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 Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 210 | FftData& E_refined = output.E_refined; |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 211 | FftData E_coarse; |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 212 | std::array<float, kBlockSize>& e_refined = output.e_refined; |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 213 | std::array<float, kBlockSize>& e_coarse = output.e_coarse; |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 214 | |
| 215 | FftData S; |
| 216 | FftData& G = S; |
| 217 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 218 | // Form the outputs of the refined and coarse filters. |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 219 | refined_filters_[ch]->Filter(render_buffer, &S); |
| 220 | PredictionError(fft_, S, y, &e_refined, &output.s_refined); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 221 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 222 | coarse_filter_[ch]->Filter(render_buffer, &S); |
| 223 | PredictionError(fft_, S, y, &e_coarse, &output.s_coarse); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 224 | |
| 225 | // Compute the signal powers in the subtractor output. |
| 226 | output.ComputeMetrics(y); |
| 227 | |
| 228 | // Adjust the filter if needed. |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 229 | bool refined_filters_adjusted = false; |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 230 | filter_misadjustment_estimators_[ch].Update(output); |
| 231 | if (filter_misadjustment_estimators_[ch].IsAdjustmentNeeded()) { |
| 232 | float scale = filter_misadjustment_estimators_[ch].GetMisadjustment(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 233 | refined_filters_[ch]->ScaleFilter(scale); |
| 234 | for (auto& h_k : refined_impulse_responses_[ch]) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 235 | h_k *= scale; |
| 236 | } |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 237 | ScaleFilterOutput(y, scale, e_refined, output.s_refined); |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 238 | filter_misadjustment_estimators_[ch].Reset(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 239 | refined_filters_adjusted = true; |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 240 | } |
| 241 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 242 | // Compute the FFts of the refined and coarse filter outputs. |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 243 | fft_.ZeroPaddedFft(e_refined, Aec3Fft::Window::kHanning, &E_refined); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 244 | fft_.ZeroPaddedFft(e_coarse, Aec3Fft::Window::kHanning, &E_coarse); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 245 | |
| 246 | // Compute spectra for future use. |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 247 | E_coarse.Spectrum(optimization_, output.E2_coarse); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 248 | E_refined.Spectrum(optimization_, output.E2_refined); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 249 | |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 250 | // Update the refined filter. |
| 251 | if (!refined_filters_adjusted) { |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame] | 252 | // 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 Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 259 | std::array<float, kFftLengthBy2Plus1> erl; |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 260 | 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 Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame] | 263 | aec_state.SaturatedCapture(), |
| 264 | disallow_leakage_diverged, &G); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 265 | } else { |
| 266 | G.re.fill(0.f); |
| 267 | G.im.fill(0.f); |
| 268 | } |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 269 | refined_filters_[ch]->Adapt(render_buffer, G, |
| 270 | &refined_impulse_responses_[ch]); |
| 271 | refined_filters_[ch]->ComputeFrequencyResponse( |
| 272 | &refined_frequency_responses_[ch]); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 273 | |
| 274 | if (ch == 0) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 275 | data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.re); |
| 276 | data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.im); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 277 | } |
| 278 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 279 | // 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 Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 283 | : 0; |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 284 | 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 Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 287 | aec_state.SaturatedCapture(), &G); |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame] | 288 | coarse_filter_reset_hangover_[ch] = |
| 289 | std::max(coarse_filter_reset_hangover_[ch] - 1, 0); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 290 | } else { |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 291 | poor_coarse_filter_counters_[ch] = 0; |
| 292 | coarse_filter_[ch]->SetFilter(refined_filters_[ch]->SizePartitions(), |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 293 | refined_filters_[ch]->GetFilter()); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 294 | coarse_gains_[ch]->Compute(X2_coarse, render_signal_analyzer, E_refined, |
| 295 | coarse_filter_[ch]->SizePartitions(), |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 296 | aec_state.SaturatedCapture(), &G); |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame] | 297 | coarse_filter_reset_hangover_[ch] = |
| 298 | config_.filter.coarse_reset_hangover_blocks; |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 299 | } |
| 300 | |
Per Åhgren | 91a892f | 2021-05-07 23:28:42 +0000 | [diff] [blame] | 301 | 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 Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 309 | if (ch == 0) { |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 310 | data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.re); |
| 311 | data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.im); |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 312 | filter_misadjustment_estimators_[ch].Dump(data_dumper_); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 313 | DumpFilters(); |
| 314 | } |
| 315 | |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 316 | std::for_each(e_refined.begin(), e_refined.end(), |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 317 | [](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); }); |
| 318 | |
| 319 | if (ch == 0) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 320 | data_dumper_->DumpWav("aec3_refined_filters_output", kBlockSize, |
| 321 | &e_refined[0], 16000, 1); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 322 | data_dumper_->DumpWav("aec3_coarse_filter_output", kBlockSize, |
| 323 | &e_coarse[0], 16000, 1); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 324 | } |
Per Åhgren | 7f5175a | 2018-07-25 16:30:54 +0200 | [diff] [blame] | 325 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 326 | } |
| 327 | |
Per Åhgren | b20b937 | 2018-07-13 00:22:54 +0200 | [diff] [blame] | 328 | void Subtractor::FilterMisadjustmentEstimator::Update( |
Per Åhgren | e4db6a1 | 2018-07-26 15:32:24 +0200 | [diff] [blame] | 329 | const SubtractorOutput& output) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 330 | e2_acum_ += output.e2_refined; |
Per Åhgren | e4db6a1 | 2018-07-26 15:32:24 +0200 | [diff] [blame] | 331 | y2_acum_ += output.y2; |
Jesús de Vicente Peña | 2e79d2b | 2018-06-29 16:35:08 +0200 | [diff] [blame] | 332 | 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 Åhgren | e4db6a1 | 2018-07-26 15:32:24 +0200 | [diff] [blame] | 336 | // Duration equal to blockSizeMs * n_blocks_ * 4. |
| 337 | overhang_ = 4; |
Jesús de Vicente Peña | 2e79d2b | 2018-06-29 16:35:08 +0200 | [diff] [blame] | 338 | } 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 | |
| 352 | void 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 | |
| 360 | void Subtractor::FilterMisadjustmentEstimator::Dump( |
| 361 | ApmDataDumper* data_dumper) const { |
| 362 | data_dumper->DumpRaw("aec3_inv_misadjustment_factor", inv_misadjustment_); |
| 363 | } |
| 364 | |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 365 | } // namespace webrtc |