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