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 | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 94 | 0.f)) { |
| 95 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 96 | refined_filters_[ch] = std::make_unique<AdaptiveFirFilter>( |
| 97 | config_.filter.refined.length_blocks, |
| 98 | config_.filter.refined_initial.length_blocks, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 99 | config.filter.config_change_duration_blocks, num_render_channels, |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 100 | optimization, data_dumper_); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 101 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 102 | coarse_filter_[ch] = std::make_unique<AdaptiveFirFilter>( |
| 103 | config_.filter.coarse.length_blocks, |
| 104 | config_.filter.coarse_initial.length_blocks, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 105 | config.filter.config_change_duration_blocks, num_render_channels, |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 106 | optimization, data_dumper_); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 107 | refined_gains_[ch] = std::make_unique<RefinedFilterUpdateGain>( |
| 108 | config_.filter.refined_initial, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 109 | config_.filter.config_change_duration_blocks); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 110 | coarse_gains_[ch] = std::make_unique<CoarseFilterUpdateGain>( |
| 111 | config_.filter.coarse_initial, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 112 | config.filter.config_change_duration_blocks); |
| 113 | } |
| 114 | |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 115 | RTC_DCHECK(data_dumper_); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 116 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 117 | for (auto& H2_k : refined_frequency_responses_[ch]) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 118 | H2_k.fill(0.f); |
| 119 | } |
Per Åhgren | d4e6904 | 2019-09-05 15:55:58 +0200 | [diff] [blame] | 120 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 121 | } |
| 122 | |
peah | 2910357 | 2017-07-11 02:54:02 -0700 | [diff] [blame] | 123 | Subtractor::~Subtractor() = default; |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 124 | |
| 125 | void Subtractor::HandleEchoPathChange( |
| 126 | const EchoPathVariability& echo_path_variability) { |
Per Åhgren | 8ba5861 | 2017-12-01 23:01:44 +0100 | [diff] [blame] | 127 | const auto full_reset = [&]() { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 128 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 129 | refined_filters_[ch]->HandleEchoPathChange(); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 130 | coarse_filter_[ch]->HandleEchoPathChange(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 131 | refined_gains_[ch]->HandleEchoPathChange(echo_path_variability); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 132 | coarse_gains_[ch]->HandleEchoPathChange(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 133 | refined_gains_[ch]->SetConfig(config_.filter.refined_initial, true); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 134 | coarse_gains_[ch]->SetConfig(config_.filter.coarse_initial, true); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 135 | refined_filters_[ch]->SetSizePartitions( |
| 136 | config_.filter.refined_initial.length_blocks, true); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 137 | coarse_filter_[ch]->SetSizePartitions( |
| 138 | config_.filter.coarse_initial.length_blocks, true); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 139 | } |
Per Åhgren | 8ba5861 | 2017-12-01 23:01:44 +0100 | [diff] [blame] | 140 | }; |
| 141 | |
Per Åhgren | 88cf050 | 2018-07-16 17:08:41 +0200 | [diff] [blame] | 142 | if (echo_path_variability.delay_change != |
| 143 | EchoPathVariability::DelayAdjustment::kNone) { |
Per Åhgren | 8ba5861 | 2017-12-01 23:01:44 +0100 | [diff] [blame] | 144 | full_reset(); |
Per Åhgren | 88cf050 | 2018-07-16 17:08:41 +0200 | [diff] [blame] | 145 | } |
| 146 | |
Gustaf Ullberg | 68d6d44 | 2019-01-29 10:08:15 +0100 | [diff] [blame] | 147 | if (echo_path_variability.gain_change) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 148 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 149 | refined_gains_[ch]->HandleEchoPathChange(echo_path_variability); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 150 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 151 | } |
| 152 | } |
| 153 | |
Per Åhgren | a98c807 | 2018-01-15 19:17:16 +0100 | [diff] [blame] | 154 | void Subtractor::ExitInitialState() { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 155 | for (size_t ch = 0; ch < num_capture_channels_; ++ch) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 156 | refined_gains_[ch]->SetConfig(config_.filter.refined, false); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 157 | coarse_gains_[ch]->SetConfig(config_.filter.coarse, false); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 158 | refined_filters_[ch]->SetSizePartitions( |
| 159 | config_.filter.refined.length_blocks, false); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 160 | coarse_filter_[ch]->SetSizePartitions(config_.filter.coarse.length_blocks, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 161 | false); |
| 162 | } |
Per Åhgren | a98c807 | 2018-01-15 19:17:16 +0100 | [diff] [blame] | 163 | } |
| 164 | |
peah | cf02cf1 | 2017-04-05 14:18:07 -0700 | [diff] [blame] | 165 | void Subtractor::Process(const RenderBuffer& render_buffer, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 166 | const std::vector<std::vector<float>>& capture, |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 167 | const RenderSignalAnalyzer& render_signal_analyzer, |
peah | 86afe9d | 2017-04-06 15:45:32 -0700 | [diff] [blame] | 168 | const AecState& aec_state, |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 169 | rtc::ArrayView<SubtractorOutput> outputs) { |
| 170 | RTC_DCHECK_EQ(num_capture_channels_, capture.size()); |
Per Åhgren | b5adc9e | 2018-01-15 13:20:20 +0100 | [diff] [blame] | 171 | |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 172 | // Compute the render powers. |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 173 | const bool same_filter_sizes = refined_filters_[0]->SizePartitions() == |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 174 | coarse_filter_[0]->SizePartitions(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 175 | std::array<float, kFftLengthBy2Plus1> X2_refined; |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 176 | std::array<float, kFftLengthBy2Plus1> X2_coarse_data; |
| 177 | auto& X2_coarse = same_filter_sizes ? X2_refined : X2_coarse_data; |
Per Åhgren | b441acf | 2019-10-05 09:07:24 +0200 | [diff] [blame] | 178 | if (same_filter_sizes) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 179 | render_buffer.SpectralSum(refined_filters_[0]->SizePartitions(), |
| 180 | &X2_refined); |
| 181 | } else if (refined_filters_[0]->SizePartitions() > |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 182 | coarse_filter_[0]->SizePartitions()) { |
| 183 | render_buffer.SpectralSums(coarse_filter_[0]->SizePartitions(), |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 184 | refined_filters_[0]->SizePartitions(), |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 185 | &X2_coarse, &X2_refined); |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 186 | } else { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 187 | render_buffer.SpectralSums(refined_filters_[0]->SizePartitions(), |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 188 | coarse_filter_[0]->SizePartitions(), &X2_refined, |
| 189 | &X2_coarse); |
Per Åhgren | ee8ad5f | 2018-08-10 21:15:48 +0200 | [diff] [blame] | 190 | } |
| 191 | |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 192 | // 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 Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 197 | FftData& E_refined = output.E_refined; |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 198 | FftData E_coarse; |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 199 | std::array<float, kBlockSize>& e_refined = output.e_refined; |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 200 | std::array<float, kBlockSize>& e_coarse = output.e_coarse; |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 201 | |
| 202 | FftData S; |
| 203 | FftData& G = S; |
| 204 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 205 | // Form the outputs of the refined and coarse filters. |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 206 | refined_filters_[ch]->Filter(render_buffer, &S); |
| 207 | PredictionError(fft_, S, y, &e_refined, &output.s_refined); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 208 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 209 | coarse_filter_[ch]->Filter(render_buffer, &S); |
| 210 | PredictionError(fft_, S, y, &e_coarse, &output.s_coarse); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 211 | |
| 212 | // Compute the signal powers in the subtractor output. |
| 213 | output.ComputeMetrics(y); |
| 214 | |
| 215 | // Adjust the filter if needed. |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 216 | bool refined_filters_adjusted = false; |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 217 | filter_misadjustment_estimators_[ch].Update(output); |
| 218 | if (filter_misadjustment_estimators_[ch].IsAdjustmentNeeded()) { |
| 219 | float scale = filter_misadjustment_estimators_[ch].GetMisadjustment(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 220 | refined_filters_[ch]->ScaleFilter(scale); |
| 221 | for (auto& h_k : refined_impulse_responses_[ch]) { |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 222 | h_k *= scale; |
| 223 | } |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 224 | ScaleFilterOutput(y, scale, e_refined, output.s_refined); |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 225 | filter_misadjustment_estimators_[ch].Reset(); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 226 | refined_filters_adjusted = true; |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 227 | } |
| 228 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 229 | // Compute the FFts of the refined and coarse filter outputs. |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 230 | fft_.ZeroPaddedFft(e_refined, Aec3Fft::Window::kHanning, &E_refined); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 231 | fft_.ZeroPaddedFft(e_coarse, Aec3Fft::Window::kHanning, &E_coarse); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 232 | |
| 233 | // Compute spectra for future use. |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 234 | E_coarse.Spectrum(optimization_, output.E2_coarse); |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 235 | E_refined.Spectrum(optimization_, output.E2_refined); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 236 | |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 237 | // Update the refined filter. |
| 238 | if (!refined_filters_adjusted) { |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame^] | 239 | // 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 Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 246 | std::array<float, kFftLengthBy2Plus1> erl; |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 247 | 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 Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame^] | 250 | aec_state.SaturatedCapture(), |
| 251 | disallow_leakage_diverged, &G); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 252 | } else { |
| 253 | G.re.fill(0.f); |
| 254 | G.im.fill(0.f); |
| 255 | } |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 256 | refined_filters_[ch]->Adapt(render_buffer, G, |
| 257 | &refined_impulse_responses_[ch]); |
| 258 | refined_filters_[ch]->ComputeFrequencyResponse( |
| 259 | &refined_frequency_responses_[ch]); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 260 | |
| 261 | if (ch == 0) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 262 | data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.re); |
| 263 | data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.im); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 264 | } |
| 265 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 266 | // 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 Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 270 | : 0; |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 271 | 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 Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 274 | aec_state.SaturatedCapture(), &G); |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame^] | 275 | coarse_filter_reset_hangover_[ch] = |
| 276 | std::max(coarse_filter_reset_hangover_[ch] - 1, 0); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 277 | } else { |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 278 | poor_coarse_filter_counters_[ch] = 0; |
| 279 | coarse_filter_[ch]->SetFilter(refined_filters_[ch]->SizePartitions(), |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 280 | refined_filters_[ch]->GetFilter()); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 281 | coarse_gains_[ch]->Compute(X2_coarse, render_signal_analyzer, E_refined, |
| 282 | coarse_filter_[ch]->SizePartitions(), |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 283 | aec_state.SaturatedCapture(), &G); |
Gustaf Ullberg | 992a96f | 2020-12-08 13:03:55 +0100 | [diff] [blame^] | 284 | coarse_filter_reset_hangover_[ch] = |
| 285 | config_.filter.coarse_reset_hangover_blocks; |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 286 | } |
| 287 | |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 288 | coarse_filter_[ch]->Adapt(render_buffer, G); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 289 | if (ch == 0) { |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 290 | data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.re); |
| 291 | data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.im); |
Per Åhgren | 119e219 | 2019-10-18 08:50:50 +0200 | [diff] [blame] | 292 | filter_misadjustment_estimators_[ch].Dump(data_dumper_); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 293 | DumpFilters(); |
| 294 | } |
| 295 | |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 296 | std::for_each(e_refined.begin(), e_refined.end(), |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 297 | [](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); }); |
| 298 | |
| 299 | if (ch == 0) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 300 | data_dumper_->DumpWav("aec3_refined_filters_output", kBlockSize, |
| 301 | &e_refined[0], 16000, 1); |
Per Åhgren | 9d66198 | 2020-03-20 11:26:48 +0100 | [diff] [blame] | 302 | data_dumper_->DumpWav("aec3_coarse_filter_output", kBlockSize, |
| 303 | &e_coarse[0], 16000, 1); |
Per Åhgren | 7bdf073 | 2019-09-25 14:53:30 +0200 | [diff] [blame] | 304 | } |
Per Åhgren | 7f5175a | 2018-07-25 16:30:54 +0200 | [diff] [blame] | 305 | } |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 306 | } |
| 307 | |
Per Åhgren | b20b937 | 2018-07-13 00:22:54 +0200 | [diff] [blame] | 308 | void Subtractor::FilterMisadjustmentEstimator::Update( |
Per Åhgren | e4db6a1 | 2018-07-26 15:32:24 +0200 | [diff] [blame] | 309 | const SubtractorOutput& output) { |
Per Åhgren | ff04511 | 2020-03-20 11:20:39 +0100 | [diff] [blame] | 310 | e2_acum_ += output.e2_refined; |
Per Åhgren | e4db6a1 | 2018-07-26 15:32:24 +0200 | [diff] [blame] | 311 | y2_acum_ += output.y2; |
Jesús de Vicente Peña | 2e79d2b | 2018-06-29 16:35:08 +0200 | [diff] [blame] | 312 | 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 Åhgren | e4db6a1 | 2018-07-26 15:32:24 +0200 | [diff] [blame] | 316 | // Duration equal to blockSizeMs * n_blocks_ * 4. |
| 317 | overhang_ = 4; |
Jesús de Vicente Peña | 2e79d2b | 2018-06-29 16:35:08 +0200 | [diff] [blame] | 318 | } 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 | |
| 332 | void 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 | |
| 340 | void Subtractor::FilterMisadjustmentEstimator::Dump( |
| 341 | ApmDataDumper* data_dumper) const { |
| 342 | data_dumper->DumpRaw("aec3_inv_misadjustment_factor", inv_misadjustment_); |
| 343 | } |
| 344 | |
peah | 522d71b | 2017-02-23 05:16:26 -0800 | [diff] [blame] | 345 | } // namespace webrtc |