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_SUBTRACTOR_H_ 12 #define MODULES_AUDIO_PROCESSING_AEC3_SUBTRACTOR_H_ 13 14 #include <math.h> 15 #include <stddef.h> 16 17 #include <array> 18 #include <vector> 19 20 #include "api/array_view.h" 21 #include "api/audio/echo_canceller3_config.h" 22 #include "modules/audio_processing/aec3/adaptive_fir_filter.h" 23 #include "modules/audio_processing/aec3/aec3_common.h" 24 #include "modules/audio_processing/aec3/aec3_fft.h" 25 #include "modules/audio_processing/aec3/aec_state.h" 26 #include "modules/audio_processing/aec3/coarse_filter_update_gain.h" 27 #include "modules/audio_processing/aec3/echo_path_variability.h" 28 #include "modules/audio_processing/aec3/refined_filter_update_gain.h" 29 #include "modules/audio_processing/aec3/render_buffer.h" 30 #include "modules/audio_processing/aec3/render_signal_analyzer.h" 31 #include "modules/audio_processing/aec3/subtractor_output.h" 32 #include "modules/audio_processing/logging/apm_data_dumper.h" 33 #include "rtc_base/checks.h" 34 35 namespace webrtc { 36 37 // Proves linear echo cancellation functionality 38 class Subtractor { 39 public: 40 Subtractor(const EchoCanceller3Config& config, 41 size_t num_render_channels, 42 size_t num_capture_channels, 43 ApmDataDumper* data_dumper, 44 Aec3Optimization optimization); 45 ~Subtractor(); 46 Subtractor(const Subtractor&) = delete; 47 Subtractor& operator=(const Subtractor&) = delete; 48 49 // Performs the echo subtraction. 50 void Process(const RenderBuffer& render_buffer, 51 const std::vector<std::vector<float>>& capture, 52 const RenderSignalAnalyzer& render_signal_analyzer, 53 const AecState& aec_state, 54 rtc::ArrayView<SubtractorOutput> outputs); 55 56 void HandleEchoPathChange(const EchoPathVariability& echo_path_variability); 57 58 // Exits the initial state. 59 void ExitInitialState(); 60 61 // Returns the block-wise frequency responses for the refined adaptive 62 // filters. 63 const std::vector<std::vector<std::array<float, kFftLengthBy2Plus1>>>& FilterFrequencyResponses()64 FilterFrequencyResponses() const { 65 return refined_frequency_responses_; 66 } 67 68 // Returns the estimates of the impulse responses for the refined adaptive 69 // filters. FilterImpulseResponses()70 const std::vector<std::vector<float>>& FilterImpulseResponses() const { 71 return refined_impulse_responses_; 72 } 73 DumpFilters()74 void DumpFilters() { 75 data_dumper_->DumpRaw( 76 "aec3_subtractor_h_refined", 77 rtc::ArrayView<const float>( 78 refined_impulse_responses_[0].data(), 79 GetTimeDomainLength( 80 refined_filters_[0]->max_filter_size_partitions()))); 81 82 refined_filters_[0]->DumpFilter("aec3_subtractor_H_refined"); 83 coarse_filter_[0]->DumpFilter("aec3_subtractor_H_coarse"); 84 } 85 86 private: 87 class FilterMisadjustmentEstimator { 88 public: 89 FilterMisadjustmentEstimator() = default; 90 ~FilterMisadjustmentEstimator() = default; 91 // Update the misadjustment estimator. 92 void Update(const SubtractorOutput& output); 93 // GetMisadjustment() Returns a recommended scale for the filter so the 94 // prediction error energy gets closer to the energy that is seen at the 95 // microphone input. GetMisadjustment()96 float GetMisadjustment() const { 97 RTC_DCHECK_GT(inv_misadjustment_, 0.0f); 98 // It is not aiming to adjust all the estimated mismatch. Instead, 99 // it adjusts half of that estimated mismatch. 100 return 2.f / sqrtf(inv_misadjustment_); 101 } 102 // Returns true if the prediciton error energy is significantly larger 103 // than the microphone signal energy and, therefore, an adjustment is 104 // recommended. IsAdjustmentNeeded()105 bool IsAdjustmentNeeded() const { return inv_misadjustment_ > 10.f; } 106 void Reset(); 107 void Dump(ApmDataDumper* data_dumper) const; 108 109 private: 110 const int n_blocks_ = 4; 111 int n_blocks_acum_ = 0; 112 float e2_acum_ = 0.f; 113 float y2_acum_ = 0.f; 114 float inv_misadjustment_ = 0.f; 115 int overhang_ = 0.f; 116 }; 117 118 const Aec3Fft fft_; 119 ApmDataDumper* data_dumper_; 120 const Aec3Optimization optimization_; 121 const EchoCanceller3Config config_; 122 const size_t num_capture_channels_; 123 124 std::vector<std::unique_ptr<AdaptiveFirFilter>> refined_filters_; 125 std::vector<std::unique_ptr<AdaptiveFirFilter>> coarse_filter_; 126 std::vector<std::unique_ptr<RefinedFilterUpdateGain>> refined_gains_; 127 std::vector<std::unique_ptr<CoarseFilterUpdateGain>> coarse_gains_; 128 std::vector<FilterMisadjustmentEstimator> filter_misadjustment_estimators_; 129 std::vector<size_t> poor_coarse_filter_counters_; 130 std::vector<std::vector<std::array<float, kFftLengthBy2Plus1>>> 131 refined_frequency_responses_; 132 std::vector<std::vector<float>> refined_impulse_responses_; 133 }; 134 135 } // namespace webrtc 136 137 #endif // MODULES_AUDIO_PROCESSING_AEC3_SUBTRACTOR_H_ 138