blob: 091a7b5116a2ad7e618a9cfe1847413e7f442ba2 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
bjornv@webrtc.org0c6f9312012-01-30 09:39:08 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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_ECHO_CANCELLATION_IMPL_H_
12#define MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_
niklase@google.com470e71d2011-07-07 08:21:25 +000013
kwiberg88788ad2016-02-19 07:04:49 -080014#include <memory>
terelius85fa7d52016-03-24 01:51:52 -070015#include <vector>
kwiberg88788ad2016-02-19 07:04:49 -080016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/audio_processing/include/audio_processing.h"
18#include "rtc_base/constructormagic.h"
19#include "rtc_base/criticalsection.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020
21namespace webrtc {
andrew@webrtc.org61e596f2013-07-25 18:28:29 +000022
niklase@google.com470e71d2011-07-07 08:21:25 +000023class AudioBuffer;
24
sazabe490b22018-10-03 17:03:13 +020025// The acoustic echo cancellation (AEC) component provides better performance
26// than AECM but also requires more processing power and is dependent on delay
27// stability and reporting accuracy. As such it is well-suited and recommended
28// for PC and IP phone applications.
29class EchoCancellationImpl {
niklase@google.com470e71d2011-07-07 08:21:25 +000030 public:
peahb58a1582016-03-15 09:34:24 -070031 EchoCancellationImpl(rtc::CriticalSection* crit_render,
peahdf3efa82015-11-28 12:35:15 -080032 rtc::CriticalSection* crit_capture);
sazabe490b22018-10-03 17:03:13 +020033 ~EchoCancellationImpl();
niklase@google.com470e71d2011-07-07 08:21:25 +000034
peah764e3642016-10-22 05:04:30 -070035 void ProcessRenderAudio(rtc::ArrayView<const float> packed_render_audio);
peahb58a1582016-03-15 09:34:24 -070036 int ProcessCaptureAudio(AudioBuffer* audio, int stream_delay_ms);
niklase@google.com470e71d2011-07-07 08:21:25 +000037
sazabe490b22018-10-03 17:03:13 +020038 int Enable(bool enable);
39 bool is_enabled() const;
40
41 // Differences in clock speed on the primary and reverse streams can impact
42 // the AEC performance. On the client-side, this could be seen when different
43 // render and capture devices are used, particularly with webcams.
44 //
45 // This enables a compensation mechanism, and requires that
46 // set_stream_drift_samples() be called.
47 int enable_drift_compensation(bool enable);
48 bool is_drift_compensation_enabled() const;
49
50 // Sets the difference between the number of samples rendered and captured by
51 // the audio devices since the last call to |ProcessStream()|. Must be called
52 // if drift compensation is enabled, prior to |ProcessStream()|.
53 void set_stream_drift_samples(int drift);
54 int stream_drift_samples() const;
55
56 enum SuppressionLevel {
57 kLowSuppression,
58 kModerateSuppression,
59 kHighSuppression
60 };
61
62 // Sets the aggressiveness of the suppressor. A higher level trades off
63 // double-talk performance for increased echo suppression.
64 int set_suppression_level(SuppressionLevel level);
65 SuppressionLevel suppression_level() const;
66
67 // Returns false if the current frame almost certainly contains no echo
68 // and true if it _might_ contain echo.
69 bool stream_has_echo() const;
70
71 // Enables the computation of various echo metrics. These are obtained
72 // through |GetMetrics()|.
73 int enable_metrics(bool enable);
74 bool are_metrics_enabled() const;
75
76 // Each statistic is reported in dB.
77 // P_far: Far-end (render) signal power.
78 // P_echo: Near-end (capture) echo signal power.
79 // P_out: Signal power at the output of the AEC.
80 // P_a: Internal signal power at the point before the AEC's non-linear
81 // processor.
82 struct Metrics {
83 // RERL = ERL + ERLE
84 AudioProcessing::Statistic residual_echo_return_loss;
85
86 // ERL = 10log_10(P_far / P_echo)
87 AudioProcessing::Statistic echo_return_loss;
88
89 // ERLE = 10log_10(P_echo / P_out)
90 AudioProcessing::Statistic echo_return_loss_enhancement;
91
92 // (Pre non-linear processing suppression) A_NLP = 10log_10(P_echo / P_a)
93 AudioProcessing::Statistic a_nlp;
94
95 // Fraction of time that the AEC linear filter is divergent, in a 1-second
96 // non-overlapped aggregation window.
97 float divergent_filter_fraction;
98 };
99
Sam Zackrissoncdf0e6d2018-09-17 11:05:17 +0200100 // Provides various statistics about the AEC.
sazabe490b22018-10-03 17:03:13 +0200101 int GetMetrics(Metrics* metrics);
102
103 // Enables computation and logging of delay values. Statistics are obtained
104 // through |GetDelayMetrics()|.
105 int enable_delay_logging(bool enable);
106 bool is_delay_logging_enabled() const;
107
Sam Zackrissoncdf0e6d2018-09-17 11:05:17 +0200108 // Provides delay metrics.
sazabe490b22018-10-03 17:03:13 +0200109 // The delay metrics consists of the delay |median| and the delay standard
110 // deviation |std|. It also consists of the fraction of delay estimates
111 // |fraction_poor_delays| that can make the echo cancellation perform poorly.
112 // The values are aggregated until the first call to |GetDelayMetrics()| and
113 // afterwards aggregated and updated every second.
114 // Note that if there are several clients pulling metrics from
115 // |GetDelayMetrics()| during a session the first call from any of them will
116 // change to one second aggregation window for all.
117 int GetDelayMetrics(int* median, int* std);
118 int GetDelayMetrics(int* median, int* std, float* fraction_poor_delays);
119
120 // Returns a pointer to the low level AEC component. In case of multiple
121 // channels, the pointer to the first one is returned. A NULL pointer is
122 // returned when the AEC component is disabled or has not been initialized
123 // successfully.
124 struct AecCore* aec_core() const;
niklase@google.com470e71d2011-07-07 08:21:25 +0000125
peahb58a1582016-03-15 09:34:24 -0700126 void Initialize(int sample_rate_hz,
127 size_t num_reverse_channels_,
128 size_t num_output_channels_,
129 size_t num_proc_channels_);
peah88ac8532016-09-12 16:47:25 -0700130 void SetExtraOptions(const webrtc::Config& config);
Minyue13b96ba2015-10-03 00:39:14 +0200131 bool is_delay_agnostic_enabled() const;
132 bool is_extended_filter_enabled() const;
peah7789fe72016-04-15 01:19:44 -0700133 std::string GetExperimentsDescription();
peah0332c2d2016-04-15 11:23:33 -0700134 bool is_refined_adaptive_filter_enabled() const;
Minyue13b96ba2015-10-03 00:39:14 +0200135
peah20028c42016-03-04 11:50:54 -0800136 // Returns the system delay of the first AEC component.
137 int GetSystemDelayInSamples() const;
138
peah764e3642016-10-22 05:04:30 -0700139 static void PackRenderAudioBuffer(const AudioBuffer* audio,
140 size_t num_output_channels,
141 size_t num_channels,
142 std::vector<float>* packed_buffer);
143 static size_t NumCancellersRequired(size_t num_output_channels,
144 size_t num_reverse_channels);
145
niklase@google.com470e71d2011-07-07 08:21:25 +0000146 private:
peahb624d8c2016-03-05 03:01:14 -0800147 class Canceller;
peahb58a1582016-03-15 09:34:24 -0700148 struct StreamProperties;
peahb624d8c2016-03-05 03:01:14 -0800149
peahfa6228e2015-11-16 16:27:42 -0800150 void AllocateRenderQueue();
peahb624d8c2016-03-05 03:01:14 -0800151 int Configure();
peahfa6228e2015-11-16 16:27:42 -0800152
danilchap56359be2017-09-07 07:53:45 -0700153 rtc::CriticalSection* const crit_render_ RTC_ACQUIRED_BEFORE(crit_capture_);
peahdf3efa82015-11-28 12:35:15 -0800154 rtc::CriticalSection* const crit_capture_;
peahfa6228e2015-11-16 16:27:42 -0800155
peahb624d8c2016-03-05 03:01:14 -0800156 bool enabled_ = false;
danilchap56359be2017-09-07 07:53:45 -0700157 bool drift_compensation_enabled_ RTC_GUARDED_BY(crit_capture_);
158 bool metrics_enabled_ RTC_GUARDED_BY(crit_capture_);
159 SuppressionLevel suppression_level_ RTC_GUARDED_BY(crit_capture_);
160 int stream_drift_samples_ RTC_GUARDED_BY(crit_capture_);
161 bool was_stream_drift_set_ RTC_GUARDED_BY(crit_capture_);
162 bool stream_has_echo_ RTC_GUARDED_BY(crit_capture_);
163 bool delay_logging_enabled_ RTC_GUARDED_BY(crit_capture_);
164 bool extended_filter_enabled_ RTC_GUARDED_BY(crit_capture_);
165 bool delay_agnostic_enabled_ RTC_GUARDED_BY(crit_capture_);
166 bool refined_adaptive_filter_enabled_ RTC_GUARDED_BY(crit_capture_) = false;
peahdf3efa82015-11-28 12:35:15 -0800167
Per Ã…hgren11556462017-12-22 16:13:57 +0100168 // Only active on Chrome OS devices.
169 const bool enforce_zero_stream_delay_ RTC_GUARDED_BY(crit_capture_);
170
peahb624d8c2016-03-05 03:01:14 -0800171 std::vector<std::unique_ptr<Canceller>> cancellers_;
peahb58a1582016-03-15 09:34:24 -0700172 std::unique_ptr<StreamProperties> stream_properties_;
173
peahb624d8c2016-03-05 03:01:14 -0800174 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCancellationImpl);
niklase@google.com470e71d2011-07-07 08:21:25 +0000175};
andrew@webrtc.org61e596f2013-07-25 18:28:29 +0000176
niklase@google.com470e71d2011-07-07 08:21:25 +0000177} // namespace webrtc
178
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200179#endif // MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_