aec_state.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. #ifndef MODULES_AUDIO_PROCESSING_AEC3_AEC_STATE_H_
  11. #define MODULES_AUDIO_PROCESSING_AEC3_AEC_STATE_H_
  12. #include <stddef.h>
  13. #include <array>
  14. #include <memory>
  15. #include <vector>
  16. #include "absl/types/optional.h"
  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/delay_estimate.h"
  21. #include "modules/audio_processing/aec3/echo_audibility.h"
  22. #include "modules/audio_processing/aec3/echo_path_variability.h"
  23. #include "modules/audio_processing/aec3/erl_estimator.h"
  24. #include "modules/audio_processing/aec3/erle_estimator.h"
  25. #include "modules/audio_processing/aec3/filter_analyzer.h"
  26. #include "modules/audio_processing/aec3/render_buffer.h"
  27. #include "modules/audio_processing/aec3/reverb_model_estimator.h"
  28. #include "modules/audio_processing/aec3/subtractor_output.h"
  29. #include "modules/audio_processing/aec3/subtractor_output_analyzer.h"
  30. #include "modules/audio_processing/aec3/transparent_mode.h"
  31. namespace webrtc {
  32. class ApmDataDumper;
  33. // Handles the state and the conditions for the echo removal functionality.
  34. class AecState {
  35. public:
  36. AecState(const EchoCanceller3Config& config, size_t num_capture_channels);
  37. ~AecState();
  38. // Returns whether the echo subtractor can be used to determine the residual
  39. // echo.
  40. bool UsableLinearEstimate() const {
  41. return filter_quality_state_.LinearFilterUsable() &&
  42. config_.filter.use_linear_filter;
  43. }
  44. // Returns whether the echo subtractor output should be used as output.
  45. bool UseLinearFilterOutput() const {
  46. return filter_quality_state_.LinearFilterUsable() &&
  47. config_.filter.use_linear_filter;
  48. }
  49. // Returns whether the render signal is currently active.
  50. bool ActiveRender() const { return blocks_with_active_render_ > 200; }
  51. // Returns the appropriate scaling of the residual echo to match the
  52. // audibility.
  53. void GetResidualEchoScaling(rtc::ArrayView<float> residual_scaling) const;
  54. // Returns whether the stationary properties of the signals are used in the
  55. // aec.
  56. bool UseStationarityProperties() const {
  57. return config_.echo_audibility.use_stationarity_properties;
  58. }
  59. // Returns the ERLE.
  60. rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> Erle() const {
  61. return erle_estimator_.Erle();
  62. }
  63. // Returns an offset to apply to the estimation of the residual echo
  64. // computation. Returning nullopt means that no offset should be used, while
  65. // any other value will be applied as a multiplier to the estimated residual
  66. // echo.
  67. absl::optional<float> ErleUncertainty() const;
  68. // Returns the fullband ERLE estimate in log2 units.
  69. float FullBandErleLog2() const { return erle_estimator_.FullbandErleLog2(); }
  70. // Returns the ERL.
  71. const std::array<float, kFftLengthBy2Plus1>& Erl() const {
  72. return erl_estimator_.Erl();
  73. }
  74. // Returns the time-domain ERL.
  75. float ErlTimeDomain() const { return erl_estimator_.ErlTimeDomain(); }
  76. // Returns the delay estimate based on the linear filter.
  77. int MinDirectPathFilterDelay() const {
  78. return delay_state_.MinDirectPathFilterDelay();
  79. }
  80. // Returns whether the capture signal is saturated.
  81. bool SaturatedCapture() const { return capture_signal_saturation_; }
  82. // Returns whether the echo signal is saturated.
  83. bool SaturatedEcho() const { return saturation_detector_.SaturatedEcho(); }
  84. // Updates the capture signal saturation.
  85. void UpdateCaptureSaturation(bool capture_signal_saturation) {
  86. capture_signal_saturation_ = capture_signal_saturation;
  87. }
  88. // Returns whether the transparent mode is active
  89. bool TransparentModeActive() const {
  90. return transparent_state_ && transparent_state_->Active();
  91. }
  92. // Takes appropriate action at an echo path change.
  93. void HandleEchoPathChange(const EchoPathVariability& echo_path_variability);
  94. // Returns the decay factor for the echo reverberation.
  95. float ReverbDecay() const { return reverb_model_estimator_.ReverbDecay(); }
  96. // Return the frequency response of the reverberant echo.
  97. rtc::ArrayView<const float> GetReverbFrequencyResponse() const {
  98. return reverb_model_estimator_.GetReverbFrequencyResponse();
  99. }
  100. // Returns whether the transition for going out of the initial stated has
  101. // been triggered.
  102. bool TransitionTriggered() const {
  103. return initial_state_.TransitionTriggered();
  104. }
  105. // Updates the aec state.
  106. // TODO(bugs.webrtc.org/10913): Compute multi-channel ERL.
  107. void Update(
  108. const absl::optional<DelayEstimate>& external_delay,
  109. rtc::ArrayView<const std::vector<std::array<float, kFftLengthBy2Plus1>>>
  110. adaptive_filter_frequency_responses,
  111. rtc::ArrayView<const std::vector<float>>
  112. adaptive_filter_impulse_responses,
  113. const RenderBuffer& render_buffer,
  114. rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> E2_refined,
  115. rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> Y2,
  116. rtc::ArrayView<const SubtractorOutput> subtractor_output);
  117. // Returns filter length in blocks.
  118. int FilterLengthBlocks() const {
  119. // All filters have the same length, so arbitrarily return channel 0 length.
  120. return filter_analyzer_.FilterLengthBlocks();
  121. }
  122. private:
  123. static int instance_count_;
  124. std::unique_ptr<ApmDataDumper> data_dumper_;
  125. const EchoCanceller3Config config_;
  126. const size_t num_capture_channels_;
  127. const bool deactivate_initial_state_reset_at_echo_path_change_;
  128. const bool full_reset_at_echo_path_change_;
  129. const bool subtractor_analyzer_reset_at_echo_path_change_;
  130. // Class for controlling the transition from the intial state, which in turn
  131. // controls when the filter parameters for the initial state should be used.
  132. class InitialState {
  133. public:
  134. explicit InitialState(const EchoCanceller3Config& config);
  135. // Resets the state to again begin in the initial state.
  136. void Reset();
  137. // Updates the state based on new data.
  138. void Update(bool active_render, bool saturated_capture);
  139. // Returns whether the initial state is active or not.
  140. bool InitialStateActive() const { return initial_state_; }
  141. // Returns that the transition from the initial state has was started.
  142. bool TransitionTriggered() const { return transition_triggered_; }
  143. private:
  144. const bool conservative_initial_phase_;
  145. const float initial_state_seconds_;
  146. bool transition_triggered_ = false;
  147. bool initial_state_ = true;
  148. size_t strong_not_saturated_render_blocks_ = 0;
  149. } initial_state_;
  150. // Class for choosing the direct-path delay relative to the beginning of the
  151. // filter, as well as any other data related to the delay used within
  152. // AecState.
  153. class FilterDelay {
  154. public:
  155. FilterDelay(const EchoCanceller3Config& config,
  156. size_t num_capture_channels);
  157. // Returns whether an external delay has been reported to the AecState (from
  158. // the delay estimator).
  159. bool ExternalDelayReported() const { return external_delay_reported_; }
  160. // Returns the delay in blocks relative to the beginning of the filter that
  161. // corresponds to the direct path of the echo.
  162. rtc::ArrayView<const int> DirectPathFilterDelays() const {
  163. return filter_delays_blocks_;
  164. }
  165. // Returns the minimum delay among the direct path delays relative to the
  166. // beginning of the filter
  167. int MinDirectPathFilterDelay() const { return min_filter_delay_; }
  168. // Updates the delay estimates based on new data.
  169. void Update(
  170. rtc::ArrayView<const int> analyzer_filter_delay_estimates_blocks,
  171. const absl::optional<DelayEstimate>& external_delay,
  172. size_t blocks_with_proper_filter_adaptation);
  173. private:
  174. const int delay_headroom_samples_;
  175. bool external_delay_reported_ = false;
  176. std::vector<int> filter_delays_blocks_;
  177. int min_filter_delay_ = 0;
  178. absl::optional<DelayEstimate> external_delay_;
  179. } delay_state_;
  180. // Classifier for toggling transparent mode when there is no echo.
  181. std::unique_ptr<TransparentMode> transparent_state_;
  182. // Class for analyzing how well the linear filter is, and can be expected to,
  183. // perform on the current signals. The purpose of this is for using to
  184. // select the echo suppression functionality as well as the input to the echo
  185. // suppressor.
  186. class FilteringQualityAnalyzer {
  187. public:
  188. FilteringQualityAnalyzer(const EchoCanceller3Config& config,
  189. size_t num_capture_channels);
  190. // Returns whether the linear filter can be used for the echo
  191. // canceller output.
  192. bool LinearFilterUsable() const { return overall_usable_linear_estimates_; }
  193. // Returns whether an individual filter output can be used for the echo
  194. // canceller output.
  195. const std::vector<bool>& UsableLinearFilterOutputs() const {
  196. return usable_linear_filter_estimates_;
  197. }
  198. // Resets the state of the analyzer.
  199. void Reset();
  200. // Updates the analysis based on new data.
  201. void Update(bool active_render,
  202. bool transparent_mode,
  203. bool saturated_capture,
  204. const absl::optional<DelayEstimate>& external_delay,
  205. bool any_filter_converged);
  206. private:
  207. const bool use_linear_filter_;
  208. bool overall_usable_linear_estimates_ = false;
  209. size_t filter_update_blocks_since_reset_ = 0;
  210. size_t filter_update_blocks_since_start_ = 0;
  211. bool convergence_seen_ = false;
  212. std::vector<bool> usable_linear_filter_estimates_;
  213. } filter_quality_state_;
  214. // Class for detecting whether the echo is to be considered to be
  215. // saturated.
  216. class SaturationDetector {
  217. public:
  218. // Returns whether the echo is to be considered saturated.
  219. bool SaturatedEcho() const { return saturated_echo_; }
  220. // Updates the detection decision based on new data.
  221. void Update(rtc::ArrayView<const std::vector<float>> x,
  222. bool saturated_capture,
  223. bool usable_linear_estimate,
  224. rtc::ArrayView<const SubtractorOutput> subtractor_output,
  225. float echo_path_gain);
  226. private:
  227. bool saturated_echo_ = false;
  228. } saturation_detector_;
  229. ErlEstimator erl_estimator_;
  230. ErleEstimator erle_estimator_;
  231. size_t strong_not_saturated_render_blocks_ = 0;
  232. size_t blocks_with_active_render_ = 0;
  233. bool capture_signal_saturation_ = false;
  234. FilterAnalyzer filter_analyzer_;
  235. EchoAudibility echo_audibility_;
  236. ReverbModelEstimator reverb_model_estimator_;
  237. ReverbModel avg_render_reverb_;
  238. SubtractorOutputAnalyzer subtractor_output_analyzer_;
  239. };
  240. } // namespace webrtc
  241. #endif // MODULES_AUDIO_PROCESSING_AEC3_AEC_STATE_H_