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