1 /* 2 * Copyright (c) 2018 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 11 #ifndef MODULES_AUDIO_PROCESSING_AEC3_REVERB_DECAY_ESTIMATOR_H_ 12 #define MODULES_AUDIO_PROCESSING_AEC3_REVERB_DECAY_ESTIMATOR_H_ 13 14 #include <array> 15 #include <vector> 16 17 #include "absl/types/optional.h" 18 #include "api/array_view.h" 19 #include "modules/audio_processing/aec3/aec3_common.h" // kMaxAdaptiveFilter... 20 21 namespace webrtc { 22 23 class ApmDataDumper; 24 struct EchoCanceller3Config; 25 26 // Class for estimating the decay of the late reverb. 27 class ReverbDecayEstimator { 28 public: 29 explicit ReverbDecayEstimator(const EchoCanceller3Config& config); 30 ~ReverbDecayEstimator(); 31 // Updates the decay estimate. 32 void Update(rtc::ArrayView<const float> filter, 33 const absl::optional<float>& filter_quality, 34 int filter_delay_blocks, 35 bool usable_linear_filter, 36 bool stationary_signal); 37 // Returns the decay for the exponential model. The parameter `mild` indicates 38 // which exponential decay to return, the default one or a milder one. Decay(bool mild)39 float Decay(bool mild) const { 40 if (use_adaptive_echo_decay_) { 41 return decay_; 42 } else { 43 return mild ? mild_decay_ : decay_; 44 } 45 } 46 // Dumps debug data. 47 void Dump(ApmDataDumper* data_dumper) const; 48 49 private: 50 void EstimateDecay(rtc::ArrayView<const float> filter, int peak_block); 51 void AnalyzeFilter(rtc::ArrayView<const float> filter); 52 53 void ResetDecayEstimation(); 54 55 // Class for estimating the decay of the late reverb from the linear filter. 56 class LateReverbLinearRegressor { 57 public: 58 // Resets the estimator to receive a specified number of data points. 59 void Reset(int num_data_points); 60 // Accumulates estimation data. 61 void Accumulate(float z); 62 // Estimates the decay. 63 float Estimate(); 64 // Returns whether an estimate is available. EstimateAvailable()65 bool EstimateAvailable() const { return n_ == N_ && N_ != 0; } 66 67 public: 68 float nz_ = 0.f; 69 float nn_ = 0.f; 70 float count_ = 0.f; 71 int N_ = 0; 72 int n_ = 0; 73 }; 74 75 // Class for identifying the length of the early reverb from the linear 76 // filter. For identifying the early reverberations, the impulse response is 77 // divided in sections and the tilt of each section is computed by a linear 78 // regressor. 79 class EarlyReverbLengthEstimator { 80 public: 81 explicit EarlyReverbLengthEstimator(int max_blocks); 82 ~EarlyReverbLengthEstimator(); 83 84 // Resets the estimator. 85 void Reset(); 86 // Accumulates estimation data. 87 void Accumulate(float value, float smoothing); 88 // Estimates the size in blocks of the early reverb. 89 int Estimate(); 90 // Dumps debug data. 91 void Dump(ApmDataDumper* data_dumper) const; 92 93 private: 94 std::vector<float> numerators_smooth_; 95 std::vector<float> numerators_; 96 int coefficients_counter_; 97 int block_counter_ = 0; 98 int n_sections_ = 0; 99 }; 100 101 const int filter_length_blocks_; 102 const int filter_length_coefficients_; 103 const bool use_adaptive_echo_decay_; 104 LateReverbLinearRegressor late_reverb_decay_estimator_; 105 EarlyReverbLengthEstimator early_reverb_estimator_; 106 int late_reverb_start_; 107 int late_reverb_end_; 108 int block_to_analyze_ = 0; 109 int estimation_region_candidate_size_ = 0; 110 bool estimation_region_identified_ = false; 111 std::vector<float> previous_gains_; 112 float decay_; 113 float mild_decay_; 114 float tail_gain_ = 0.f; 115 float smoothing_constant_ = 0.f; 116 }; 117 118 } // namespace webrtc 119 120 #endif // MODULES_AUDIO_PROCESSING_AEC3_REVERB_DECAY_ESTIMATOR_H_ 121