xref: /aosp_15_r20/external/webrtc/modules/audio_processing/aec3/filter_analyzer.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 
11 #ifndef MODULES_AUDIO_PROCESSING_AEC3_FILTER_ANALYZER_H_
12 #define MODULES_AUDIO_PROCESSING_AEC3_FILTER_ANALYZER_H_
13 
14 #include <stddef.h>
15 
16 #include <array>
17 #include <atomic>
18 #include <memory>
19 #include <vector>
20 
21 #include "api/array_view.h"
22 #include "api/audio/echo_canceller3_config.h"
23 #include "modules/audio_processing/aec3/aec3_common.h"
24 #include "modules/audio_processing/aec3/block.h"
25 
26 namespace webrtc {
27 
28 class ApmDataDumper;
29 class RenderBuffer;
30 
31 // Class for analyzing the properties of an adaptive filter.
32 class FilterAnalyzer {
33  public:
34   FilterAnalyzer(const EchoCanceller3Config& config,
35                  size_t num_capture_channels);
36   ~FilterAnalyzer();
37 
38   FilterAnalyzer(const FilterAnalyzer&) = delete;
39   FilterAnalyzer& operator=(const FilterAnalyzer&) = delete;
40 
41   // Resets the analysis.
42   void Reset();
43 
44   // Updates the estimates with new input data.
45   void Update(rtc::ArrayView<const std::vector<float>> filters_time_domain,
46               const RenderBuffer& render_buffer,
47               bool* any_filter_consistent,
48               float* max_echo_path_gain);
49 
50   // Returns the delay in blocks for each filter.
FilterDelaysBlocks()51   rtc::ArrayView<const int> FilterDelaysBlocks() const {
52     return filter_delays_blocks_;
53   }
54 
55   // Returns the minimum delay of all filters in terms of blocks.
MinFilterDelayBlocks()56   int MinFilterDelayBlocks() const { return min_filter_delay_blocks_; }
57 
58   // Returns the number of blocks for the current used filter.
FilterLengthBlocks()59   int FilterLengthBlocks() const {
60     return filter_analysis_states_[0].filter_length_blocks;
61   }
62 
63   // Returns the preprocessed filter.
GetAdjustedFilters()64   rtc::ArrayView<const std::vector<float>> GetAdjustedFilters() const {
65     return h_highpass_;
66   }
67 
68   // Public for testing purposes only.
69   void SetRegionToAnalyze(size_t filter_size);
70 
71  private:
72   struct FilterAnalysisState;
73 
74   void AnalyzeRegion(
75       rtc::ArrayView<const std::vector<float>> filters_time_domain,
76       const RenderBuffer& render_buffer);
77 
78   void UpdateFilterGain(rtc::ArrayView<const float> filters_time_domain,
79                         FilterAnalysisState* st);
80   void PreProcessFilters(
81       rtc::ArrayView<const std::vector<float>> filters_time_domain);
82 
83   void ResetRegion();
84 
85   struct FilterRegion {
86     size_t start_sample_;
87     size_t end_sample_;
88   };
89 
90   // This class checks whether the shape of the impulse response has been
91   // consistent over time.
92   class ConsistentFilterDetector {
93    public:
94     explicit ConsistentFilterDetector(const EchoCanceller3Config& config);
95     void Reset();
96     bool Detect(rtc::ArrayView<const float> filter_to_analyze,
97                 const FilterRegion& region,
98                 const Block& x_block,
99                 size_t peak_index,
100                 int delay_blocks);
101 
102    private:
103     bool significant_peak_;
104     float filter_floor_accum_;
105     float filter_secondary_peak_;
106     size_t filter_floor_low_limit_;
107     size_t filter_floor_high_limit_;
108     const float active_render_threshold_;
109     size_t consistent_estimate_counter_ = 0;
110     int consistent_delay_reference_ = -10;
111   };
112 
113   struct FilterAnalysisState {
FilterAnalysisStateFilterAnalysisState114     explicit FilterAnalysisState(const EchoCanceller3Config& config)
115         : filter_length_blocks(config.filter.refined_initial.length_blocks),
116           consistent_filter_detector(config) {
117       Reset(config.ep_strength.default_gain);
118     }
119 
ResetFilterAnalysisState120     void Reset(float default_gain) {
121       peak_index = 0;
122       gain = default_gain;
123       consistent_filter_detector.Reset();
124     }
125 
126     float gain;
127     size_t peak_index;
128     int filter_length_blocks;
129     bool consistent_estimate = false;
130     ConsistentFilterDetector consistent_filter_detector;
131   };
132 
133   static std::atomic<int> instance_count_;
134   std::unique_ptr<ApmDataDumper> data_dumper_;
135   const bool bounded_erl_;
136   const float default_gain_;
137   std::vector<std::vector<float>> h_highpass_;
138 
139   size_t blocks_since_reset_ = 0;
140   FilterRegion region_;
141 
142   std::vector<FilterAnalysisState> filter_analysis_states_;
143   std::vector<int> filter_delays_blocks_;
144 
145   int min_filter_delay_blocks_ = 0;
146 };
147 
148 }  // namespace webrtc
149 
150 #endif  // MODULES_AUDIO_PROCESSING_AEC3_FILTER_ANALYZER_H_
151