blob: a4aab4987fccf4621b053572021678185c9f4011 [file] [log] [blame]
peahe0eae3c2016-12-14 01:16:23 -08001/*
2 * Copyright (c) 2016 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_ECHO_CANCELLER3_H_
12#define MODULES_AUDIO_PROCESSING_AEC3_ECHO_CANCELLER3_H_
peahe0eae3c2016-12-14 01:16:23 -080013
Yves Gerey988cc082018-10-23 12:03:01 +020014#include <stddef.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020015
Yves Gerey988cc082018-10-23 12:03:01 +020016#include <memory>
17#include <vector>
18
19#include "api/array_view.h"
Gustaf Ullberg3646f972018-02-14 15:19:04 +010020#include "api/audio/echo_canceller3_config.h"
Yves Gerey988cc082018-10-23 12:03:01 +020021#include "api/audio/echo_control.h"
Per Åhgren14f252a2018-11-27 18:02:56 +010022#include "modules/audio_processing/aec3/api_call_jitter_metrics.h"
Per Åhgren398689f2018-08-23 11:38:27 +020023#include "modules/audio_processing/aec3/block_delay_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "modules/audio_processing/aec3/block_framer.h"
25#include "modules/audio_processing/aec3/block_processor.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "modules/audio_processing/aec3/frame_blocker.h"
27#include "modules/audio_processing/audio_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "modules/audio_processing/logging/apm_data_dumper.h"
Yves Gerey988cc082018-10-23 12:03:01 +020029#include "rtc_base/checks.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "rtc_base/race_checker.h"
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +000031#include "rtc_base/swap_queue.h"
Yves Gerey988cc082018-10-23 12:03:01 +020032#include "rtc_base/thread_annotations.h"
peahe0eae3c2016-12-14 01:16:23 -080033
34namespace webrtc {
35
Per Åhgren80e52162020-04-06 14:57:52 +020036// Method for adjusting config parameter dependencies.
37// Only to be used externally to AEC3 for testing purposes.
38// TODO(webrtc:5298): Move this to a separate file.
39EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config);
40
peahd0263542017-01-03 04:20:34 -080041// Functor for verifying the invariance of the frames being put into the render
42// queue.
43class Aec3RenderQueueItemVerifier {
44 public:
Per Åhgrence202a02019-09-02 17:01:19 +020045 Aec3RenderQueueItemVerifier(size_t num_bands,
46 size_t num_channels,
47 size_t frame_length)
48 : num_bands_(num_bands),
49 num_channels_(num_channels),
50 frame_length_(frame_length) {}
peahd0263542017-01-03 04:20:34 -080051
Per Åhgrence202a02019-09-02 17:01:19 +020052 bool operator()(const std::vector<std::vector<std::vector<float>>>& v) const {
peahd0263542017-01-03 04:20:34 -080053 if (v.size() != num_bands_) {
54 return false;
55 }
Per Åhgrence202a02019-09-02 17:01:19 +020056 for (const auto& band : v) {
57 if (band.size() != num_channels_) {
peahd0263542017-01-03 04:20:34 -080058 return false;
59 }
Per Åhgrence202a02019-09-02 17:01:19 +020060 for (const auto& channel : band) {
61 if (channel.size() != frame_length_) {
62 return false;
63 }
64 }
peahd0263542017-01-03 04:20:34 -080065 }
66 return true;
67 }
68
69 private:
70 const size_t num_bands_;
Per Åhgrence202a02019-09-02 17:01:19 +020071 const size_t num_channels_;
peahd0263542017-01-03 04:20:34 -080072 const size_t frame_length_;
73};
74
75// Main class for the echo canceller3.
76// It does 4 things:
77// -Receives 10 ms frames of band-split audio.
peahd0263542017-01-03 04:20:34 -080078// -Provides the lower level echo canceller functionality with
79// blocks of 64 samples of audio data.
80// -Partially handles the jitter in the render and capture API
81// call sequence.
82//
83// The class is supposed to be used in a non-concurrent manner apart from the
84// AnalyzeRender call which can be called concurrently with the other methods.
Gustaf Ullbergc5222982017-10-05 10:25:05 +020085class EchoCanceller3 : public EchoControl {
peahe0eae3c2016-12-14 01:16:23 -080086 public:
peahd0263542017-01-03 04:20:34 -080087 // Normal c-tor to use.
Per Åhgrence202a02019-09-02 17:01:19 +020088 EchoCanceller3(const EchoCanceller3Config& config,
89 int sample_rate_hz,
90 size_t num_render_channels,
91 size_t num_capture_channels);
peahd0263542017-01-03 04:20:34 -080092 // Testing c-tor that is used only for testing purposes.
Per Åhgren8ba58612017-12-01 23:01:44 +010093 EchoCanceller3(const EchoCanceller3Config& config,
94 int sample_rate_hz,
Per Åhgrence202a02019-09-02 17:01:19 +020095 size_t num_render_channels,
96 size_t num_capture_channels,
peahd0263542017-01-03 04:20:34 -080097 std::unique_ptr<BlockProcessor> block_processor);
Gustaf Ullbergc5222982017-10-05 10:25:05 +020098 ~EchoCanceller3() override;
Per Åhgrence202a02019-09-02 17:01:19 +020099 EchoCanceller3(const EchoCanceller3&) = delete;
100 EchoCanceller3& operator=(const EchoCanceller3&) = delete;
101
peahe0eae3c2016-12-14 01:16:23 -0800102 // Analyzes and stores an internal copy of the split-band domain render
103 // signal.
Per Åhgren0aefbf02019-08-23 21:29:17 +0200104 void AnalyzeRender(AudioBuffer* render) override { AnalyzeRender(*render); }
peahe0eae3c2016-12-14 01:16:23 -0800105 // Analyzes the full-band domain capture signal to detect signal saturation.
Per Åhgren0aefbf02019-08-23 21:29:17 +0200106 void AnalyzeCapture(AudioBuffer* capture) override {
107 AnalyzeCapture(*capture);
108 }
peahe0eae3c2016-12-14 01:16:23 -0800109 // Processes the split-band domain capture signal in order to remove any echo
110 // present in the signal.
Gustaf Ullbergc5222982017-10-05 10:25:05 +0200111 void ProcessCapture(AudioBuffer* capture, bool level_change) override;
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100112 // As above, but also returns the linear filter output.
113 void ProcessCapture(AudioBuffer* capture,
114 AudioBuffer* linear_output,
115 bool level_change) override;
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100116 // Collect current metrics from the echo canceller.
117 Metrics GetMetrics() const override;
Per Åhgrend0fa8202018-04-18 09:35:13 +0200118 // Provides an optional external estimate of the audio buffer delay.
Gustaf Ullberg3cb61042019-10-24 15:52:10 +0200119 void SetAudioBufferDelay(int delay_ms) override;
peahe0eae3c2016-12-14 01:16:23 -0800120
Per Åhgren652ada52021-03-03 10:52:44 +0000121 // Specifies whether the capture output will be used. The purpose of this is
122 // to allow the echo controller to deactivate some of the processing when the
123 // resulting output is anyway not used, for instance when the endpoint is
124 // muted.
125 void SetCaptureOutputUsage(bool capture_output_used) override;
126
Gustaf Ullberg8675eee2019-10-09 13:34:36 +0200127 bool ActiveProcessing() const override;
128
peahd0263542017-01-03 04:20:34 -0800129 // Signals whether an external detector has detected echo leakage from the
130 // echo canceller.
131 // Note that in the case echo leakage has been flagged, it should be unflagged
132 // once it is no longer occurring.
peah69221db2017-01-27 03:28:19 -0800133 void UpdateEchoLeakageStatus(bool leakage_detected) {
peahd0263542017-01-03 04:20:34 -0800134 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
peah69221db2017-01-27 03:28:19 -0800135 block_processor_->UpdateEchoLeakageStatus(leakage_detected);
peahd0263542017-01-03 04:20:34 -0800136 }
137
Per Åhgrenb2b58d82019-12-02 14:59:40 +0100138 // Produces a default configuration that is suitable for a certain combination
139 // of render and capture channels.
140 static EchoCanceller3Config CreateDefaultConfig(size_t num_render_channels,
141 size_t num_capture_channels);
142
peahe0eae3c2016-12-14 01:16:23 -0800143 private:
peahd0263542017-01-03 04:20:34 -0800144 class RenderWriter;
145
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000146 // Empties the render SwapQueue.
peahcf02cf12017-04-05 14:18:07 -0700147 void EmptyRenderQueue();
peahd0263542017-01-03 04:20:34 -0800148
Per Åhgren0aefbf02019-08-23 21:29:17 +0200149 // Analyzes and stores an internal copy of the split-band domain render
150 // signal.
151 void AnalyzeRender(const AudioBuffer& render);
152 // Analyzes the full-band domain capture signal to detect signal saturation.
153 void AnalyzeCapture(const AudioBuffer& capture);
154
peahd0263542017-01-03 04:20:34 -0800155 rtc::RaceChecker capture_race_checker_;
156 rtc::RaceChecker render_race_checker_;
157
158 // State that is accessed by the AnalyzeRender call.
danilchap56359be2017-09-07 07:53:45 -0700159 std::unique_ptr<RenderWriter> render_writer_
160 RTC_GUARDED_BY(render_race_checker_);
peahd0263542017-01-03 04:20:34 -0800161
162 // State that may be accessed by the capture thread.
peahe0eae3c2016-12-14 01:16:23 -0800163 static int instance_count_;
peahd0263542017-01-03 04:20:34 -0800164 std::unique_ptr<ApmDataDumper> data_dumper_;
Per Åhgren398689f2018-08-23 11:38:27 +0200165 const EchoCanceller3Config config_;
peahd0263542017-01-03 04:20:34 -0800166 const int sample_rate_hz_;
167 const int num_bands_;
Per Åhgrence202a02019-09-02 17:01:19 +0200168 const size_t num_render_channels_;
169 const size_t num_capture_channels_;
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100170 std::unique_ptr<BlockFramer> linear_output_framer_
171 RTC_GUARDED_BY(capture_race_checker_);
danilchap56359be2017-09-07 07:53:45 -0700172 BlockFramer output_framer_ RTC_GUARDED_BY(capture_race_checker_);
173 FrameBlocker capture_blocker_ RTC_GUARDED_BY(capture_race_checker_);
174 FrameBlocker render_blocker_ RTC_GUARDED_BY(capture_race_checker_);
Per Åhgrence202a02019-09-02 17:01:19 +0200175 SwapQueue<std::vector<std::vector<std::vector<float>>>,
176 Aec3RenderQueueItemVerifier>
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000177 render_transfer_queue_;
peahd0263542017-01-03 04:20:34 -0800178 std::unique_ptr<BlockProcessor> block_processor_
danilchap56359be2017-09-07 07:53:45 -0700179 RTC_GUARDED_BY(capture_race_checker_);
Per Åhgrence202a02019-09-02 17:01:19 +0200180 std::vector<std::vector<std::vector<float>>> render_queue_output_frame_
danilchap56359be2017-09-07 07:53:45 -0700181 RTC_GUARDED_BY(capture_race_checker_);
danilchap56359be2017-09-07 07:53:45 -0700182 bool saturated_microphone_signal_ RTC_GUARDED_BY(capture_race_checker_) =
183 false;
Per Åhgrence202a02019-09-02 17:01:19 +0200184 std::vector<std::vector<std::vector<float>>> render_block_
185 RTC_GUARDED_BY(capture_race_checker_);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100186 std::unique_ptr<std::vector<std::vector<std::vector<float>>>>
187 linear_output_block_ RTC_GUARDED_BY(capture_race_checker_);
Per Åhgrence202a02019-09-02 17:01:19 +0200188 std::vector<std::vector<std::vector<float>>> capture_block_
189 RTC_GUARDED_BY(capture_race_checker_);
190 std::vector<std::vector<rtc::ArrayView<float>>> render_sub_frame_view_
191 RTC_GUARDED_BY(capture_race_checker_);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100192 std::vector<std::vector<rtc::ArrayView<float>>> linear_output_sub_frame_view_
193 RTC_GUARDED_BY(capture_race_checker_);
Per Åhgrence202a02019-09-02 17:01:19 +0200194 std::vector<std::vector<rtc::ArrayView<float>>> capture_sub_frame_view_
danilchap56359be2017-09-07 07:53:45 -0700195 RTC_GUARDED_BY(capture_race_checker_);
Per Åhgren260c7882020-01-28 15:38:41 +0100196 std::unique_ptr<BlockDelayBuffer> block_delay_buffer_
197 RTC_GUARDED_BY(capture_race_checker_);
Per Åhgren14f252a2018-11-27 18:02:56 +0100198 ApiCallJitterMetrics api_call_metrics_ RTC_GUARDED_BY(capture_race_checker_);
peahe0eae3c2016-12-14 01:16:23 -0800199};
200} // namespace webrtc
201
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200202#endif // MODULES_AUDIO_PROCESSING_AEC3_ECHO_CANCELLER3_H_