blob: 72c7e52a7725579c542ed5e53c19280f6cd4b918 [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
Yves Gerey988cc082018-10-23 12:03:01 +020014#include <stddef.h>
kwiberg88788ad2016-02-19 07:04:49 -080015#include <memory>
Yves Gerey988cc082018-10-23 12:03:01 +020016#include <string>
terelius85fa7d52016-03-24 01:51:52 -070017#include <vector>
kwiberg88788ad2016-02-19 07:04:49 -080018
Yves Gerey988cc082018-10-23 12:03:01 +020019#include "api/array_view.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "modules/audio_processing/include/audio_processing.h"
21#include "rtc_base/constructormagic.h"
22#include "rtc_base/criticalsection.h"
Yves Gerey988cc082018-10-23 12:03:01 +020023#include "rtc_base/thread_annotations.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000024
25namespace webrtc {
andrew@webrtc.org61e596f2013-07-25 18:28:29 +000026
niklase@google.com470e71d2011-07-07 08:21:25 +000027class AudioBuffer;
28
sazabe490b22018-10-03 17:03:13 +020029// The acoustic echo cancellation (AEC) component provides better performance
30// than AECM but also requires more processing power and is dependent on delay
31// stability and reporting accuracy. As such it is well-suited and recommended
32// for PC and IP phone applications.
33class EchoCancellationImpl {
niklase@google.com470e71d2011-07-07 08:21:25 +000034 public:
Sam Zackrisson7f4dfa42018-11-01 08:59:29 +010035 explicit EchoCancellationImpl();
sazabe490b22018-10-03 17:03:13 +020036 ~EchoCancellationImpl();
niklase@google.com470e71d2011-07-07 08:21:25 +000037
peah764e3642016-10-22 05:04:30 -070038 void ProcessRenderAudio(rtc::ArrayView<const float> packed_render_audio);
peahb58a1582016-03-15 09:34:24 -070039 int ProcessCaptureAudio(AudioBuffer* audio, int stream_delay_ms);
niklase@google.com470e71d2011-07-07 08:21:25 +000040
sazabe490b22018-10-03 17:03:13 +020041 int Enable(bool enable);
42 bool is_enabled() const;
43
44 // Differences in clock speed on the primary and reverse streams can impact
45 // the AEC performance. On the client-side, this could be seen when different
46 // render and capture devices are used, particularly with webcams.
47 //
48 // This enables a compensation mechanism, and requires that
49 // set_stream_drift_samples() be called.
50 int enable_drift_compensation(bool enable);
51 bool is_drift_compensation_enabled() const;
52
53 // Sets the difference between the number of samples rendered and captured by
54 // the audio devices since the last call to |ProcessStream()|. Must be called
55 // if drift compensation is enabled, prior to |ProcessStream()|.
56 void set_stream_drift_samples(int drift);
57 int stream_drift_samples() const;
58
59 enum SuppressionLevel {
60 kLowSuppression,
61 kModerateSuppression,
62 kHighSuppression
63 };
64
65 // Sets the aggressiveness of the suppressor. A higher level trades off
66 // double-talk performance for increased echo suppression.
67 int set_suppression_level(SuppressionLevel level);
68 SuppressionLevel suppression_level() const;
69
70 // Returns false if the current frame almost certainly contains no echo
71 // and true if it _might_ contain echo.
72 bool stream_has_echo() const;
73
74 // Enables the computation of various echo metrics. These are obtained
75 // through |GetMetrics()|.
76 int enable_metrics(bool enable);
77 bool are_metrics_enabled() const;
78
79 // Each statistic is reported in dB.
80 // P_far: Far-end (render) signal power.
81 // P_echo: Near-end (capture) echo signal power.
82 // P_out: Signal power at the output of the AEC.
83 // P_a: Internal signal power at the point before the AEC's non-linear
84 // processor.
85 struct Metrics {
86 // RERL = ERL + ERLE
87 AudioProcessing::Statistic residual_echo_return_loss;
88
89 // ERL = 10log_10(P_far / P_echo)
90 AudioProcessing::Statistic echo_return_loss;
91
92 // ERLE = 10log_10(P_echo / P_out)
93 AudioProcessing::Statistic echo_return_loss_enhancement;
94
95 // (Pre non-linear processing suppression) A_NLP = 10log_10(P_echo / P_a)
96 AudioProcessing::Statistic a_nlp;
97
98 // Fraction of time that the AEC linear filter is divergent, in a 1-second
99 // non-overlapped aggregation window.
100 float divergent_filter_fraction;
101 };
102
Sam Zackrissoncdf0e6d2018-09-17 11:05:17 +0200103 // Provides various statistics about the AEC.
sazabe490b22018-10-03 17:03:13 +0200104 int GetMetrics(Metrics* metrics);
105
106 // Enables computation and logging of delay values. Statistics are obtained
107 // through |GetDelayMetrics()|.
108 int enable_delay_logging(bool enable);
109 bool is_delay_logging_enabled() const;
110
Sam Zackrissoncdf0e6d2018-09-17 11:05:17 +0200111 // Provides delay metrics.
sazabe490b22018-10-03 17:03:13 +0200112 // The delay metrics consists of the delay |median| and the delay standard
113 // deviation |std|. It also consists of the fraction of delay estimates
114 // |fraction_poor_delays| that can make the echo cancellation perform poorly.
115 // The values are aggregated until the first call to |GetDelayMetrics()| and
116 // afterwards aggregated and updated every second.
117 // Note that if there are several clients pulling metrics from
118 // |GetDelayMetrics()| during a session the first call from any of them will
119 // change to one second aggregation window for all.
120 int GetDelayMetrics(int* median, int* std);
121 int GetDelayMetrics(int* median, int* std, float* fraction_poor_delays);
122
123 // Returns a pointer to the low level AEC component. In case of multiple
124 // channels, the pointer to the first one is returned. A NULL pointer is
125 // returned when the AEC component is disabled or has not been initialized
126 // successfully.
127 struct AecCore* aec_core() const;
niklase@google.com470e71d2011-07-07 08:21:25 +0000128
peahb58a1582016-03-15 09:34:24 -0700129 void Initialize(int sample_rate_hz,
130 size_t num_reverse_channels_,
131 size_t num_output_channels_,
132 size_t num_proc_channels_);
peah88ac8532016-09-12 16:47:25 -0700133 void SetExtraOptions(const webrtc::Config& config);
Minyue13b96ba2015-10-03 00:39:14 +0200134 bool is_delay_agnostic_enabled() const;
135 bool is_extended_filter_enabled() const;
peah7789fe72016-04-15 01:19:44 -0700136 std::string GetExperimentsDescription();
peah0332c2d2016-04-15 11:23:33 -0700137 bool is_refined_adaptive_filter_enabled() const;
Minyue13b96ba2015-10-03 00:39:14 +0200138
peah20028c42016-03-04 11:50:54 -0800139 // Returns the system delay of the first AEC component.
140 int GetSystemDelayInSamples() const;
141
peah764e3642016-10-22 05:04:30 -0700142 static void PackRenderAudioBuffer(const AudioBuffer* audio,
143 size_t num_output_channels,
144 size_t num_channels,
145 std::vector<float>* packed_buffer);
146 static size_t NumCancellersRequired(size_t num_output_channels,
147 size_t num_reverse_channels);
148
niklase@google.com470e71d2011-07-07 08:21:25 +0000149 private:
peahb624d8c2016-03-05 03:01:14 -0800150 class Canceller;
peahb58a1582016-03-15 09:34:24 -0700151 struct StreamProperties;
peahb624d8c2016-03-05 03:01:14 -0800152
peahfa6228e2015-11-16 16:27:42 -0800153 void AllocateRenderQueue();
peahb624d8c2016-03-05 03:01:14 -0800154 int Configure();
peahfa6228e2015-11-16 16:27:42 -0800155
peahb624d8c2016-03-05 03:01:14 -0800156 bool enabled_ = false;
Sam Zackrisson7f4dfa42018-11-01 08:59:29 +0100157 bool drift_compensation_enabled_;
158 bool metrics_enabled_;
159 SuppressionLevel suppression_level_;
160 int stream_drift_samples_;
161 bool was_stream_drift_set_;
162 bool stream_has_echo_;
163 bool delay_logging_enabled_;
164 bool extended_filter_enabled_;
165 bool delay_agnostic_enabled_;
166 bool refined_adaptive_filter_enabled_ = false;
peahdf3efa82015-11-28 12:35:15 -0800167
Per Åhgren11556462017-12-22 16:13:57 +0100168 // Only active on Chrome OS devices.
Sam Zackrisson7f4dfa42018-11-01 08:59:29 +0100169 const bool enforce_zero_stream_delay_;
Per Åhgren11556462017-12-22 16:13:57 +0100170
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_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000173};
andrew@webrtc.org61e596f2013-07-25 18:28:29 +0000174
niklase@google.com470e71d2011-07-07 08:21:25 +0000175} // namespace webrtc
176
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200177#endif // MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_