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 <array> 15 #include <memory> 16 #include <vector> 17 18 #include "api/array_view.h" 19 #include "modules/audio_processing/aec3/aec3_common.h" 20 #include "modules/audio_processing/aec3/aec3_fft.h" 21 #include "modules/audio_processing/aec3/fft_data.h" 22 #include "modules/audio_processing/aec3/render_buffer.h" 23 #include "modules/audio_processing/logging/apm_data_dumper.h" 24 #include "rtc_base/constructormagic.h" 25 26 namespace webrtc { 27 namespace aec3 { 28 // Computes and stores the frequency response of the filter. 29 void UpdateFrequencyResponse( 30 rtc::ArrayView<const FftData> H, 31 std::vector<std::array<float, kFftLengthBy2Plus1>>* H2); 32 #if defined(WEBRTC_HAS_NEON) 33 void UpdateFrequencyResponse_NEON( 34 rtc::ArrayView<const FftData> H, 35 std::vector<std::array<float, kFftLengthBy2Plus1>>* H2); 36 #endif 37 #if defined(WEBRTC_ARCH_X86_FAMILY) 38 void UpdateFrequencyResponse_SSE2( 39 rtc::ArrayView<const FftData> H, 40 std::vector<std::array<float, kFftLengthBy2Plus1>>* H2); 41 #endif 42 43 // Computes and stores the echo return loss estimate of the filter, which is the 44 // sum of the partition frequency responses. 45 void UpdateErlEstimator( 46 const std::vector<std::array<float, kFftLengthBy2Plus1>>& H2, 47 std::array<float, kFftLengthBy2Plus1>* erl); 48 #if defined(WEBRTC_HAS_NEON) 49 void UpdateErlEstimator_NEON( 50 const std::vector<std::array<float, kFftLengthBy2Plus1>>& H2, 51 std::array<float, kFftLengthBy2Plus1>* erl); 52 #endif 53 #if defined(WEBRTC_ARCH_X86_FAMILY) 54 void UpdateErlEstimator_SSE2( 55 const std::vector<std::array<float, kFftLengthBy2Plus1>>& H2, 56 std::array<float, kFftLengthBy2Plus1>* erl); 57 #endif 58 59 // Adapts the filter partitions. 60 void AdaptPartitions(const RenderBuffer& render_buffer, 61 const FftData& G, 62 rtc::ArrayView<FftData> H); 63 #if defined(WEBRTC_HAS_NEON) 64 void AdaptPartitions_NEON(const RenderBuffer& render_buffer, 65 const FftData& G, 66 rtc::ArrayView<FftData> H); 67 #endif 68 #if defined(WEBRTC_ARCH_X86_FAMILY) 69 void AdaptPartitions_SSE2(const RenderBuffer& render_buffer, 70 const FftData& G, 71 rtc::ArrayView<FftData> H); 72 #endif 73 74 // Produces the filter output. 75 void ApplyFilter(const RenderBuffer& render_buffer, 76 rtc::ArrayView<const FftData> H, 77 FftData* S); 78 #if defined(WEBRTC_HAS_NEON) 79 void ApplyFilter_NEON(const RenderBuffer& render_buffer, 80 rtc::ArrayView<const FftData> H, 81 FftData* S); 82 #endif 83 #if defined(WEBRTC_ARCH_X86_FAMILY) 84 void ApplyFilter_SSE2(const RenderBuffer& render_buffer, 85 rtc::ArrayView<const FftData> H, 86 FftData* S); 87 #endif 88 89 } // namespace aec3 90 91 // Provides a frequency domain adaptive filter functionality. 92 class AdaptiveFirFilter { 93 public: 94 AdaptiveFirFilter(size_t size_partitions, 95 Aec3Optimization optimization, 96 ApmDataDumper* data_dumper); 97 98 ~AdaptiveFirFilter(); 99 100 // Produces the output of the filter. 101 void Filter(const RenderBuffer& render_buffer, FftData* S) const; 102 103 // Adapts the filter. 104 void Adapt(const RenderBuffer& render_buffer, const FftData& G); 105 106 // Receives reports that known echo path changes have occured and adjusts 107 // the filter adaptation accordingly. 108 void HandleEchoPathChange(); 109 110 // Returns the filter size. SizePartitions()111 size_t SizePartitions() const { return H_.size(); } 112 113 // Returns the filter based echo return loss. Erl()114 const std::array<float, kFftLengthBy2Plus1>& Erl() const { return erl_; } 115 116 // Returns the frequency responses for the filter partitions. 117 const std::vector<std::array<float, kFftLengthBy2Plus1>>& FilterFrequencyResponse()118 FilterFrequencyResponse() const { 119 return H2_; 120 } 121 122 // Returns the estimate of the impulse response. 123 const std::array<float, kAdaptiveFilterTimeDomainLength>& FilterImpulseResponse()124 FilterImpulseResponse() const { 125 return h_; 126 } 127 DumpFilter(const char * name)128 void DumpFilter(const char* name) { 129 for (auto& H : H_) { 130 data_dumper_->DumpRaw(name, H.re); 131 data_dumper_->DumpRaw(name, H.im); 132 } 133 } 134 135 private: 136 // Constrain the filter partitions in a cyclic manner. 137 void Constrain(); 138 139 ApmDataDumper* const data_dumper_; 140 const Aec3Fft fft_; 141 const Aec3Optimization optimization_; 142 std::vector<FftData> H_; 143 std::vector<std::array<float, kFftLengthBy2Plus1>> H2_; 144 std::array<float, kAdaptiveFilterTimeDomainLength> h_; 145 std::array<float, kFftLengthBy2Plus1> erl_; 146 size_t partition_to_constrain_ = 0; 147 148 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveFirFilter); 149 }; 150 151 } // namespace webrtc 152 153 #endif // MODULES_AUDIO_PROCESSING_AEC3_ADAPTIVE_FIR_FILTER_H_ 154