1 /*
2  *  Copyright (c) 2018 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_SIGNAL_DEPENDENT_ERLE_ESTIMATOR_H_
12 #define MODULES_AUDIO_PROCESSING_AEC3_SIGNAL_DEPENDENT_ERLE_ESTIMATOR_H_
13 
14 #include <memory>
15 #include <vector>
16 
17 #include "api/array_view.h"
18 #include "api/audio/echo_canceller3_config.h"
19 #include "modules/audio_processing/aec3/aec3_common.h"
20 #include "modules/audio_processing/aec3/render_buffer.h"
21 #include "modules/audio_processing/logging/apm_data_dumper.h"
22 
23 namespace webrtc {
24 
25 // This class estimates the dependency of the Erle to the input signal. By
26 // looking at the input signal, an estimation on whether the current echo
27 // estimate is due to the direct path or to a more reverberant one is performed.
28 // Once that estimation is done, it is possible to refine the average Erle that
29 // this class receive as an input.
30 class SignalDependentErleEstimator {
31  public:
32   SignalDependentErleEstimator(const EchoCanceller3Config& config,
33                                size_t num_capture_channels);
34 
35   ~SignalDependentErleEstimator();
36 
37   void Reset();
38 
39   // Returns the Erle per frequency subband.
Erle()40   rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> Erle() const {
41     return erle_;
42   }
43 
44   // Updates the Erle estimate. The Erle that is passed as an input is required
45   // to be an estimation of the average Erle achieved by the linear filter.
46   void Update(
47       const RenderBuffer& render_buffer,
48       rtc::ArrayView<const std::vector<std::array<float, kFftLengthBy2Plus1>>>
49           filter_frequency_response,
50       rtc::ArrayView<const float, kFftLengthBy2Plus1> X2,
51       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> Y2,
52       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> E2,
53       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> average_erle,
54       const std::vector<bool>& converged_filters);
55 
56   void Dump(const std::unique_ptr<ApmDataDumper>& data_dumper) const;
57 
58   static constexpr size_t kSubbands = 6;
59 
60  private:
61   void ComputeNumberOfActiveFilterSections(
62       const RenderBuffer& render_buffer,
63       rtc::ArrayView<const std::vector<std::array<float, kFftLengthBy2Plus1>>>
64           filter_frequency_responses);
65 
66   void UpdateCorrectionFactors(
67       rtc::ArrayView<const float, kFftLengthBy2Plus1> X2,
68       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> Y2,
69       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> E2,
70       const std::vector<bool>& converged_filters);
71 
72   void ComputeEchoEstimatePerFilterSection(
73       const RenderBuffer& render_buffer,
74       rtc::ArrayView<const std::vector<std::array<float, kFftLengthBy2Plus1>>>
75           filter_frequency_responses);
76 
77   void ComputeActiveFilterSections();
78 
79   const float min_erle_;
80   const size_t num_sections_;
81   const size_t num_blocks_;
82   const size_t delay_headroom_blocks_;
83   const std::array<size_t, kFftLengthBy2Plus1> band_to_subband_;
84   const std::array<float, kSubbands> max_erle_;
85   const std::vector<size_t> section_boundaries_blocks_;
86   std::vector<std::array<float, kFftLengthBy2Plus1>> erle_;
87   std::vector<std::vector<std::array<float, kFftLengthBy2Plus1>>>
88       S2_section_accum_;
89   std::vector<std::vector<std::array<float, kSubbands>>> erle_estimators_;
90   std::vector<std::array<float, kSubbands>> erle_ref_;
91   std::vector<std::vector<std::array<float, kSubbands>>> correction_factors_;
92   std::vector<std::array<int, kSubbands>> num_updates_;
93   std::vector<std::array<size_t, kFftLengthBy2Plus1>> n_active_sections_;
94 };
95 
96 }  // namespace webrtc
97 
98 #endif  // MODULES_AUDIO_PROCESSING_AEC3_SIGNAL_DEPENDENT_ERLE_ESTIMATOR_H_
99