• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SUPPRESSION_GAIN_H_
12 #define MODULES_AUDIO_PROCESSING_AEC3_SUPPRESSION_GAIN_H_
13 
14 #include <array>
15 #include <atomic>
16 #include <memory>
17 #include <vector>
18 
19 #include "absl/types/optional.h"
20 #include "api/array_view.h"
21 #include "api/audio/echo_canceller3_config.h"
22 #include "modules/audio_processing/aec3/aec3_common.h"
23 #include "modules/audio_processing/aec3/aec_state.h"
24 #include "modules/audio_processing/aec3/fft_data.h"
25 #include "modules/audio_processing/aec3/moving_average.h"
26 #include "modules/audio_processing/aec3/nearend_detector.h"
27 #include "modules/audio_processing/aec3/render_signal_analyzer.h"
28 #include "modules/audio_processing/logging/apm_data_dumper.h"
29 
30 namespace webrtc {
31 
32 class SuppressionGain {
33  public:
34   SuppressionGain(const EchoCanceller3Config& config,
35                   Aec3Optimization optimization,
36                   int sample_rate_hz,
37                   size_t num_capture_channels);
38   ~SuppressionGain();
39 
40   SuppressionGain(const SuppressionGain&) = delete;
41   SuppressionGain& operator=(const SuppressionGain&) = delete;
42 
43   void GetGain(
44       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>>
45           nearend_spectrum,
46       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> echo_spectrum,
47       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>>
48           residual_echo_spectrum,
49       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>>
50           residual_echo_spectrum_unbounded,
51       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>>
52           comfort_noise_spectrum,
53       const RenderSignalAnalyzer& render_signal_analyzer,
54       const AecState& aec_state,
55       const Block& render,
56       bool clock_drift,
57       float* high_bands_gain,
58       std::array<float, kFftLengthBy2Plus1>* low_band_gain);
59 
IsDominantNearend()60   bool IsDominantNearend() {
61     return dominant_nearend_detector_->IsNearendState();
62   }
63 
64   // Toggles the usage of the initial state.
65   void SetInitialState(bool state);
66 
67  private:
68   // Computes the gain to apply for the bands beyond the first band.
69   float UpperBandsGain(
70       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> echo_spectrum,
71       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>>
72           comfort_noise_spectrum,
73       const absl::optional<int>& narrow_peak_band,
74       bool saturated_echo,
75       const Block& render,
76       const std::array<float, kFftLengthBy2Plus1>& low_band_gain) const;
77 
78   void GainToNoAudibleEcho(const std::array<float, kFftLengthBy2Plus1>& nearend,
79                            const std::array<float, kFftLengthBy2Plus1>& echo,
80                            const std::array<float, kFftLengthBy2Plus1>& masker,
81                            std::array<float, kFftLengthBy2Plus1>* gain) const;
82 
83   void LowerBandGain(
84       bool stationary_with_low_power,
85       const AecState& aec_state,
86       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>>
87           suppressor_input,
88       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> residual_echo,
89       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> comfort_noise,
90       bool clock_drift,
91       std::array<float, kFftLengthBy2Plus1>* gain);
92 
93   void GetMinGain(rtc::ArrayView<const float> weighted_residual_echo,
94                   rtc::ArrayView<const float> last_nearend,
95                   rtc::ArrayView<const float> last_echo,
96                   bool low_noise_render,
97                   bool saturated_echo,
98                   rtc::ArrayView<float> min_gain) const;
99 
100   void GetMaxGain(rtc::ArrayView<float> max_gain) const;
101 
102   class LowNoiseRenderDetector {
103    public:
104     bool Detect(const Block& render);
105 
106    private:
107     float average_power_ = 32768.f * 32768.f;
108   };
109 
110   struct GainParameters {
111     explicit GainParameters(
112         int last_lf_band,
113         int first_hf_band,
114         const EchoCanceller3Config::Suppressor::Tuning& tuning);
115     const float max_inc_factor;
116     const float max_dec_factor_lf;
117     std::array<float, kFftLengthBy2Plus1> enr_transparent_;
118     std::array<float, kFftLengthBy2Plus1> enr_suppress_;
119     std::array<float, kFftLengthBy2Plus1> emr_transparent_;
120   };
121 
122   static std::atomic<int> instance_count_;
123   std::unique_ptr<ApmDataDumper> data_dumper_;
124   const Aec3Optimization optimization_;
125   const EchoCanceller3Config config_;
126   const size_t num_capture_channels_;
127   const int state_change_duration_blocks_;
128   std::array<float, kFftLengthBy2Plus1> last_gain_;
129   std::vector<std::array<float, kFftLengthBy2Plus1>> last_nearend_;
130   std::vector<std::array<float, kFftLengthBy2Plus1>> last_echo_;
131   LowNoiseRenderDetector low_render_detector_;
132   bool initial_state_ = true;
133   int initial_state_change_counter_ = 0;
134   std::vector<aec3::MovingAverage> nearend_smoothers_;
135   const GainParameters nearend_params_;
136   const GainParameters normal_params_;
137   // Determines if the dominant nearend detector uses the unbounded residual
138   // echo spectrum.
139   const bool use_unbounded_echo_spectrum_;
140   std::unique_ptr<NearendDetector> dominant_nearend_detector_;
141 };
142 
143 }  // namespace webrtc
144 
145 #endif  // MODULES_AUDIO_PROCESSING_AEC3_SUPPRESSION_GAIN_H_
146