xref: /aosp_15_r20/external/webrtc/modules/audio_processing/aec3/adaptive_fir_filter.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_ADAPTIVE_FIR_FILTER_H_
12 #define MODULES_AUDIO_PROCESSING_AEC3_ADAPTIVE_FIR_FILTER_H_
13 
14 #include <stddef.h>
15 
16 #include <array>
17 #include <vector>
18 
19 #include "absl/strings/string_view.h"
20 #include "api/array_view.h"
21 #include "modules/audio_processing/aec3/aec3_common.h"
22 #include "modules/audio_processing/aec3/aec3_fft.h"
23 #include "modules/audio_processing/aec3/fft_data.h"
24 #include "modules/audio_processing/aec3/render_buffer.h"
25 #include "modules/audio_processing/logging/apm_data_dumper.h"
26 #include "rtc_base/system/arch.h"
27 
28 namespace webrtc {
29 namespace aec3 {
30 // Computes and stores the frequency response of the filter.
31 void ComputeFrequencyResponse(
32     size_t num_partitions,
33     const std::vector<std::vector<FftData>>& H,
34     std::vector<std::array<float, kFftLengthBy2Plus1>>* H2);
35 #if defined(WEBRTC_HAS_NEON)
36 void ComputeFrequencyResponse_Neon(
37     size_t num_partitions,
38     const std::vector<std::vector<FftData>>& H,
39     std::vector<std::array<float, kFftLengthBy2Plus1>>* H2);
40 #endif
41 #if defined(WEBRTC_ARCH_X86_FAMILY)
42 void ComputeFrequencyResponse_Sse2(
43     size_t num_partitions,
44     const std::vector<std::vector<FftData>>& H,
45     std::vector<std::array<float, kFftLengthBy2Plus1>>* H2);
46 
47 void ComputeFrequencyResponse_Avx2(
48     size_t num_partitions,
49     const std::vector<std::vector<FftData>>& H,
50     std::vector<std::array<float, kFftLengthBy2Plus1>>* H2);
51 #endif
52 
53 // Adapts the filter partitions.
54 void AdaptPartitions(const RenderBuffer& render_buffer,
55                      const FftData& G,
56                      size_t num_partitions,
57                      std::vector<std::vector<FftData>>* H);
58 #if defined(WEBRTC_HAS_NEON)
59 void AdaptPartitions_Neon(const RenderBuffer& render_buffer,
60                           const FftData& G,
61                           size_t num_partitions,
62                           std::vector<std::vector<FftData>>* H);
63 #endif
64 #if defined(WEBRTC_ARCH_X86_FAMILY)
65 void AdaptPartitions_Sse2(const RenderBuffer& render_buffer,
66                           const FftData& G,
67                           size_t num_partitions,
68                           std::vector<std::vector<FftData>>* H);
69 
70 void AdaptPartitions_Avx2(const RenderBuffer& render_buffer,
71                           const FftData& G,
72                           size_t num_partitions,
73                           std::vector<std::vector<FftData>>* H);
74 #endif
75 
76 // Produces the filter output.
77 void ApplyFilter(const RenderBuffer& render_buffer,
78                  size_t num_partitions,
79                  const std::vector<std::vector<FftData>>& H,
80                  FftData* S);
81 #if defined(WEBRTC_HAS_NEON)
82 void ApplyFilter_Neon(const RenderBuffer& render_buffer,
83                       size_t num_partitions,
84                       const std::vector<std::vector<FftData>>& H,
85                       FftData* S);
86 #endif
87 #if defined(WEBRTC_ARCH_X86_FAMILY)
88 void ApplyFilter_Sse2(const RenderBuffer& render_buffer,
89                       size_t num_partitions,
90                       const std::vector<std::vector<FftData>>& H,
91                       FftData* S);
92 
93 void ApplyFilter_Avx2(const RenderBuffer& render_buffer,
94                       size_t num_partitions,
95                       const std::vector<std::vector<FftData>>& H,
96                       FftData* S);
97 #endif
98 
99 }  // namespace aec3
100 
101 // Provides a frequency domain adaptive filter functionality.
102 class AdaptiveFirFilter {
103  public:
104   AdaptiveFirFilter(size_t max_size_partitions,
105                     size_t initial_size_partitions,
106                     size_t size_change_duration_blocks,
107                     size_t num_render_channels,
108                     Aec3Optimization optimization,
109                     ApmDataDumper* data_dumper);
110 
111   ~AdaptiveFirFilter();
112 
113   AdaptiveFirFilter(const AdaptiveFirFilter&) = delete;
114   AdaptiveFirFilter& operator=(const AdaptiveFirFilter&) = delete;
115 
116   // Produces the output of the filter.
117   void Filter(const RenderBuffer& render_buffer, FftData* S) const;
118 
119   // Adapts the filter and updates an externally stored impulse response
120   // estimate.
121   void Adapt(const RenderBuffer& render_buffer,
122              const FftData& G,
123              std::vector<float>* impulse_response);
124 
125   // Adapts the filter.
126   void Adapt(const RenderBuffer& render_buffer, const FftData& G);
127 
128   // Receives reports that known echo path changes have occured and adjusts
129   // the filter adaptation accordingly.
130   void HandleEchoPathChange();
131 
132   // Returns the filter size.
SizePartitions()133   size_t SizePartitions() const { return current_size_partitions_; }
134 
135   // Sets the filter size.
136   void SetSizePartitions(size_t size, bool immediate_effect);
137 
138   // Computes the frequency responses for the filter partitions.
139   void ComputeFrequencyResponse(
140       std::vector<std::array<float, kFftLengthBy2Plus1>>* H2) const;
141 
142   // Returns the maximum number of partitions for the filter.
max_filter_size_partitions()143   size_t max_filter_size_partitions() const { return max_size_partitions_; }
144 
DumpFilter(absl::string_view name_frequency_domain)145   void DumpFilter(absl::string_view name_frequency_domain) {
146     for (size_t p = 0; p < max_size_partitions_; ++p) {
147       data_dumper_->DumpRaw(name_frequency_domain, H_[p][0].re);
148       data_dumper_->DumpRaw(name_frequency_domain, H_[p][0].im);
149     }
150   }
151 
152   // Scale the filter impulse response and spectrum by a factor.
153   void ScaleFilter(float factor);
154 
155   // Set the filter coefficients.
156   void SetFilter(size_t num_partitions,
157                  const std::vector<std::vector<FftData>>& H);
158 
159   // Gets the filter coefficients.
GetFilter()160   const std::vector<std::vector<FftData>>& GetFilter() const { return H_; }
161 
162  private:
163   // Adapts the filter and updates the filter size.
164   void AdaptAndUpdateSize(const RenderBuffer& render_buffer, const FftData& G);
165 
166   // Constrain the filter partitions in a cyclic manner.
167   void Constrain();
168   // Constrains the filter in a cyclic manner and updates the corresponding
169   // values in the supplied impulse response.
170   void ConstrainAndUpdateImpulseResponse(std::vector<float>* impulse_response);
171 
172   // Gradually Updates the current filter size towards the target size.
173   void UpdateSize();
174 
175   ApmDataDumper* const data_dumper_;
176   const Aec3Fft fft_;
177   const Aec3Optimization optimization_;
178   const size_t num_render_channels_;
179   const size_t max_size_partitions_;
180   const int size_change_duration_blocks_;
181   float one_by_size_change_duration_blocks_;
182   size_t current_size_partitions_;
183   size_t target_size_partitions_;
184   size_t old_target_size_partitions_;
185   int size_change_counter_ = 0;
186   std::vector<std::vector<FftData>> H_;
187   size_t partition_to_constrain_ = 0;
188 };
189 
190 }  // namespace webrtc
191 
192 #endif  // MODULES_AUDIO_PROCESSING_AEC3_ADAPTIVE_FIR_FILTER_H_
193