blob: 968704e4c054c62845f86801e92e49a88afeb2e0 [file] [log] [blame]
peah522d71b2017-02-23 05:16:26 -08001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef MODULES_AUDIO_PROCESSING_AEC3_AEC_STATE_H_
12#define MODULES_AUDIO_PROCESSING_AEC3_AEC_STATE_H_
peah522d71b2017-02-23 05:16:26 -080013
Christian Schuldtf4e99db2018-03-01 11:32:50 +010014#include <math.h>
15
peah522d71b2017-02-23 05:16:26 -080016#include <algorithm>
17#include <memory>
18#include <vector>
19
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "api/array_view.h"
Gustaf Ullberg3646f972018-02-14 15:19:04 +010021#include "api/audio/echo_canceller3_config.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "api/optional.h"
23#include "modules/audio_processing/aec3/aec3_common.h"
Per Åhgren3ab308f2018-02-21 08:46:03 +010024#include "modules/audio_processing/aec3/delay_estimate.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "modules/audio_processing/aec3/echo_path_variability.h"
26#include "modules/audio_processing/aec3/erl_estimator.h"
27#include "modules/audio_processing/aec3/erle_estimator.h"
Per Åhgren5c532d32018-03-22 00:29:25 +010028#include "modules/audio_processing/aec3/filter_analyzer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "modules/audio_processing/aec3/render_buffer.h"
Per Åhgren12eb8582018-03-06 10:40:51 +010030#include "modules/audio_processing/aec3/suppression_gain_limiter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/constructormagic.h"
peah522d71b2017-02-23 05:16:26 -080032
33namespace webrtc {
34
35class ApmDataDumper;
36
37// Handles the state and the conditions for the echo removal functionality.
38class AecState {
39 public:
Gustaf Ullbergbd83b912017-10-18 12:32:42 +020040 explicit AecState(const EchoCanceller3Config& config);
peah522d71b2017-02-23 05:16:26 -080041 ~AecState();
42
Per Åhgren4b3bc0f2017-12-20 15:26:13 +010043 // Returns whether the echo subtractor can be used to determine the residual
44 // echo.
peah522d71b2017-02-23 05:16:26 -080045 bool UsableLinearEstimate() const { return usable_linear_estimate_; }
46
Per Åhgren5c532d32018-03-22 00:29:25 +010047 // Returns whether the echo subtractor output should be used as output.
48 bool UseLinearFilterOutput() const { return use_linear_filter_output_; }
49
50 // Returns the estimated echo path gain.
51 bool EchoPathGain() const { return filter_analyzer_.Gain(); }
peah522d71b2017-02-23 05:16:26 -080052
peah522d71b2017-02-23 05:16:26 -080053 // Returns whether the render signal is currently active.
Per Åhgren4b3bc0f2017-12-20 15:26:13 +010054 bool ActiveRender() const { return blocks_with_active_render_ > 200; }
peahebe77782017-02-27 07:29:21 -080055
peah522d71b2017-02-23 05:16:26 -080056 // Returns the ERLE.
57 const std::array<float, kFftLengthBy2Plus1>& Erle() const {
58 return erle_estimator_.Erle();
59 }
60
Gustaf Ullberg332150d2017-11-22 14:17:39 +010061 // Returns the time-domain ERLE.
62 float ErleTimeDomain() const { return erle_estimator_.ErleTimeDomain(); }
63
peah522d71b2017-02-23 05:16:26 -080064 // Returns the ERL.
65 const std::array<float, kFftLengthBy2Plus1>& Erl() const {
66 return erl_estimator_.Erl();
67 }
68
Gustaf Ullberg332150d2017-11-22 14:17:39 +010069 // Returns the time-domain ERL.
70 float ErlTimeDomain() const { return erl_estimator_.ErlTimeDomain(); }
71
peah522d71b2017-02-23 05:16:26 -080072 // Returns the delay estimate based on the linear filter.
Per Åhgren5c532d32018-03-22 00:29:25 +010073 int FilterDelayBlocks() const { return filter_delay_blocks_; }
74
75 // Returns the internal delay estimate based on the linear filter.
76 rtc::Optional<int> InternalDelay() const { return internal_delay_; }
peah522d71b2017-02-23 05:16:26 -080077
peah522d71b2017-02-23 05:16:26 -080078 // Returns whether the capture signal is saturated.
79 bool SaturatedCapture() const { return capture_signal_saturation_; }
80
peah86afe9d2017-04-06 15:45:32 -070081 // Returns whether the echo signal is saturated.
82 bool SaturatedEcho() const { return echo_saturation_; }
83
peah522d71b2017-02-23 05:16:26 -080084 // Updates the capture signal saturation.
85 void UpdateCaptureSaturation(bool capture_signal_saturation) {
86 capture_signal_saturation_ = capture_signal_saturation;
87 }
88
Per Åhgren1b4059e2017-10-15 20:19:21 +020089 // Returns whether the transparent mode is active
90 bool TransparentMode() const { return transparent_mode_; }
peah522d71b2017-02-23 05:16:26 -080091
peah86afe9d2017-04-06 15:45:32 -070092 // Takes appropriate action at an echo path change.
93 void HandleEchoPathChange(const EchoPathVariability& echo_path_variability);
94
peah89420452017-04-07 06:13:39 -070095 // Returns the decay factor for the echo reverberation.
peah29103572017-07-11 02:54:02 -070096 float ReverbDecay() const { return reverb_decay_; }
peah89420452017-04-07 06:13:39 -070097
Per Åhgrenb6b00dc2018-02-20 22:18:27 +010098 // Returns the upper limit for the echo suppression gain.
Per Åhgren12eb8582018-03-06 10:40:51 +010099 float SuppressionGainLimit() const {
100 return suppression_gain_limiter_.Limit();
101 }
peah6d822ad2017-04-10 13:52:14 -0700102
Per Åhgren4b3bc0f2017-12-20 15:26:13 +0100103 // Returns whether the linear filter should have been able to properly adapt.
104 bool FilterHasHadTimeToConverge() const {
105 return filter_has_had_time_to_converge_;
106 }
Per Åhgren1b4059e2017-10-15 20:19:21 +0200107
Per Åhgrena98c8072018-01-15 19:17:16 +0100108 // Returns whether the filter adaptation is still in the initial state.
109 bool InitialState() const { return initial_state_; }
110
peah522d71b2017-02-23 05:16:26 -0800111 // Updates the aec state.
Per Åhgren5c532d32018-03-22 00:29:25 +0100112 void Update(const rtc::Optional<DelayEstimate>& external_delay,
Per Åhgren3ab308f2018-02-21 08:46:03 +0100113 const std::vector<std::array<float, kFftLengthBy2Plus1>>&
peah86afe9d2017-04-06 15:45:32 -0700114 adaptive_filter_frequency_response,
Per Åhgren09a718a2017-12-11 22:28:45 +0100115 const std::vector<float>& adaptive_filter_impulse_response,
Per Åhgren1b4059e2017-10-15 20:19:21 +0200116 bool converged_filter,
Per Åhgren5c532d32018-03-22 00:29:25 +0100117 bool diverged_filter,
peah86afe9d2017-04-06 15:45:32 -0700118 const RenderBuffer& render_buffer,
peah522d71b2017-02-23 05:16:26 -0800119 const std::array<float, kFftLengthBy2Plus1>& E2_main,
peah522d71b2017-02-23 05:16:26 -0800120 const std::array<float, kFftLengthBy2Plus1>& Y2,
Per Åhgren5c532d32018-03-22 00:29:25 +0100121 const std::array<float, kBlockSize>& s);
peah522d71b2017-02-23 05:16:26 -0800122
123 private:
Per Åhgren09a718a2017-12-11 22:28:45 +0100124 void UpdateReverb(const std::vector<float>& impulse_response);
Per Åhgren4b3bc0f2017-12-20 15:26:13 +0100125 bool DetectActiveRender(rtc::ArrayView<const float> x) const;
Per Åhgrenb6b00dc2018-02-20 22:18:27 +0100126 void UpdateSuppressorGainLimit(bool render_activity);
Per Åhgren31122d62018-04-10 16:33:55 +0200127 bool DetectEchoSaturation(rtc::ArrayView<const float> x,
128 float echo_path_gain);
peah29103572017-07-11 02:54:02 -0700129
peah522d71b2017-02-23 05:16:26 -0800130 static int instance_count_;
131 std::unique_ptr<ApmDataDumper> data_dumper_;
132 ErlEstimator erl_estimator_;
133 ErleEstimator erle_estimator_;
Per Åhgren1b4059e2017-10-15 20:19:21 +0200134 size_t capture_block_counter_ = 0;
Per Åhgren5c532d32018-03-22 00:29:25 +0100135 size_t blocks_since_reset_ = 0;
Per Åhgren4b3bc0f2017-12-20 15:26:13 +0100136 size_t blocks_with_proper_filter_adaptation_ = 0;
137 size_t blocks_with_active_render_ = 0;
peah522d71b2017-02-23 05:16:26 -0800138 bool usable_linear_estimate_ = false;
peah522d71b2017-02-23 05:16:26 -0800139 bool capture_signal_saturation_ = false;
peah86afe9d2017-04-06 15:45:32 -0700140 bool echo_saturation_ = false;
Per Åhgren1b4059e2017-10-15 20:19:21 +0200141 bool transparent_mode_ = false;
peahe52a2032017-04-19 09:03:40 -0700142 bool render_received_ = false;
Per Åhgren5c532d32018-03-22 00:29:25 +0100143 int filter_delay_blocks_ = 0;
peah86afe9d2017-04-06 15:45:32 -0700144 size_t blocks_since_last_saturation_ = 1000;
Christian Schuldtf4e99db2018-03-01 11:32:50 +0100145 float tail_energy_ = 0.f;
146 float accumulated_nz_ = 0.f;
147 float accumulated_nn_ = 0.f;
148 float accumulated_count_ = 0.f;
149 size_t current_reverb_decay_section_ = 0;
150 size_t num_reverb_decay_sections_ = 0;
151 size_t num_reverb_decay_sections_next_ = 0;
152 bool found_end_of_reverb_decay_ = false;
153 bool main_filter_is_adapting_ = true;
154 std::array<float, kMaxAdaptiveFilterLength> block_energies_;
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200155 const EchoCanceller3Config config_;
Per Åhgren09a718a2017-12-11 22:28:45 +0100156 std::vector<float> max_render_;
Christian Schuldtf4e99db2018-03-01 11:32:50 +0100157 float reverb_decay_ = fabsf(config_.ep_strength.default_len);
Per Åhgren4b3bc0f2017-12-20 15:26:13 +0100158 bool filter_has_had_time_to_converge_ = false;
Per Åhgrena98c8072018-01-15 19:17:16 +0100159 bool initial_state_ = true;
Per Åhgrenb6b00dc2018-02-20 22:18:27 +0100160 const float gain_rampup_increase_;
Per Åhgren12eb8582018-03-06 10:40:51 +0100161 SuppressionGainUpperLimiter suppression_gain_limiter_;
Per Åhgren5c532d32018-03-22 00:29:25 +0100162 FilterAnalyzer filter_analyzer_;
163 bool use_linear_filter_output_ = false;
164 rtc::Optional<int> internal_delay_;
165 size_t diverged_blocks_ = 0;
166 bool filter_should_have_converged_ = false;
167 size_t blocks_since_converged_filter_;
168 size_t active_blocks_since_consistent_filter_estimate_;
169 bool converged_filter_seen_ = false;
170 bool consistent_filter_seen_ = false;
171 bool external_delay_seen_ = false;
Per Åhgrenf3e2bf12018-03-22 10:15:59 +0100172 size_t converged_filter_count_ = 0;
173 bool finite_erl_ = false;
Per Åhgren8131eb02018-03-28 18:13:41 +0200174 size_t active_blocks_since_converged_filter_ = 0;
peah29103572017-07-11 02:54:02 -0700175
peah8cee56f2017-08-24 22:36:53 -0700176 RTC_DISALLOW_COPY_AND_ASSIGN(AecState);
peah522d71b2017-02-23 05:16:26 -0800177};
178
179} // namespace webrtc
180
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200181#endif // MODULES_AUDIO_PROCESSING_AEC3_AEC_STATE_H_