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