blob: a68ae01a986e68fafd729904216a08d83f4dffe2 [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 */
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020010#include "modules/audio_processing/aec3/echo_canceller3.h"
peahe0eae3c2016-12-14 01:16:23 -080011
Yves Gerey988cc082018-10-23 12:03:01 +020012#include <algorithm>
13#include <utility>
14
15#include "modules/audio_processing/aec3/aec3_common.h"
Per Åhgren0aefbf02019-08-23 21:29:17 +020016#include "modules/audio_processing/high_pass_filter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/audio_processing/logging/apm_data_dumper.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/atomic_ops.h"
Per Åhgrenc20a19c2019-11-13 11:12:29 +010019#include "rtc_base/logging.h"
Gustaf Ullberg9249fbf2019-03-14 11:24:54 +010020#include "system_wrappers/include/field_trial.h"
peahe0eae3c2016-12-14 01:16:23 -080021
22namespace webrtc {
23
peahd0263542017-01-03 04:20:34 -080024namespace {
25
peahcf02cf12017-04-05 14:18:07 -070026enum class EchoCanceller3ApiCall { kCapture, kRender };
27
peahd0263542017-01-03 04:20:34 -080028bool DetectSaturation(rtc::ArrayView<const float> y) {
29 for (auto y_k : y) {
peah522d71b2017-02-23 05:16:26 -080030 if (y_k >= 32700.0f || y_k <= -32700.0f) {
peahd0263542017-01-03 04:20:34 -080031 return true;
32 }
33 }
34 return false;
35}
36
Per Åhgren251c7352018-03-28 16:31:57 +020037// Method for adjusting config parameter dependencies..
38EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) {
39 EchoCanceller3Config adjusted_cfg = config;
Gustaf Ullberg9249fbf2019-03-14 11:24:54 +010040
41 if (field_trial::IsEnabled("WebRTC-Aec3ShortHeadroomKillSwitch")) {
42 // Two blocks headroom.
43 adjusted_cfg.delay.delay_headroom_samples = kBlockSize * 2;
44 }
45
Per Åhgren8be669f2019-10-11 23:02:26 +020046 if (field_trial::IsEnabled("WebRTC-Aec3ClampInstQualityToZeroKillSwitch")) {
47 adjusted_cfg.erle.clamp_quality_estimate_to_zero = false;
48 }
49
50 if (field_trial::IsEnabled("WebRTC-Aec3ClampInstQualityToOneKillSwitch")) {
51 adjusted_cfg.erle.clamp_quality_estimate_to_one = false;
52 }
53
Per Åhgren251c7352018-03-28 16:31:57 +020054 return adjusted_cfg;
55}
56
Per Åhgrence202a02019-09-02 17:01:19 +020057void FillSubFrameView(
58 AudioBuffer* frame,
59 size_t sub_frame_index,
60 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
peahd0263542017-01-03 04:20:34 -080061 RTC_DCHECK_GE(1, sub_frame_index);
62 RTC_DCHECK_LE(0, sub_frame_index);
63 RTC_DCHECK_EQ(frame->num_bands(), sub_frame_view->size());
Per Åhgrence202a02019-09-02 17:01:19 +020064 RTC_DCHECK_EQ(frame->num_channels(), (*sub_frame_view)[0].size());
65 for (size_t band = 0; band < sub_frame_view->size(); ++band) {
66 for (size_t channel = 0; channel < (*sub_frame_view)[0].size(); ++channel) {
67 (*sub_frame_view)[band][channel] = rtc::ArrayView<float>(
68 &frame->split_bands(channel)[band][sub_frame_index * kSubFrameLength],
69 kSubFrameLength);
70 }
peahd0263542017-01-03 04:20:34 -080071 }
72}
73
Per Åhgrence202a02019-09-02 17:01:19 +020074void FillSubFrameView(
75 std::vector<std::vector<std::vector<float>>>* frame,
76 size_t sub_frame_index,
77 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
peahd0263542017-01-03 04:20:34 -080078 RTC_DCHECK_GE(1, sub_frame_index);
79 RTC_DCHECK_EQ(frame->size(), sub_frame_view->size());
Per Åhgrence202a02019-09-02 17:01:19 +020080 RTC_DCHECK_EQ((*frame)[0].size(), (*sub_frame_view)[0].size());
81 for (size_t band = 0; band < frame->size(); ++band) {
82 for (size_t channel = 0; channel < (*frame)[band].size(); ++channel) {
83 (*sub_frame_view)[band][channel] = rtc::ArrayView<float>(
84 &(*frame)[band][channel][sub_frame_index * kSubFrameLength],
85 kSubFrameLength);
86 }
peahd0263542017-01-03 04:20:34 -080087 }
88}
89
90void ProcessCaptureFrameContent(
Per Åhgrenc20a19c2019-11-13 11:12:29 +010091 AudioBuffer* linear_output,
peahd0263542017-01-03 04:20:34 -080092 AudioBuffer* capture,
peah69221db2017-01-27 03:28:19 -080093 bool level_change,
peahd0263542017-01-03 04:20:34 -080094 bool saturated_microphone_signal,
95 size_t sub_frame_index,
96 FrameBlocker* capture_blocker,
Per Åhgrenc20a19c2019-11-13 11:12:29 +010097 BlockFramer* linear_output_framer,
peahd0263542017-01-03 04:20:34 -080098 BlockFramer* output_framer,
99 BlockProcessor* block_processor,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100100 std::vector<std::vector<std::vector<float>>>* linear_output_block,
101 std::vector<std::vector<rtc::ArrayView<float>>>*
102 linear_output_sub_frame_view,
103 std::vector<std::vector<std::vector<float>>>* capture_block,
104 std::vector<std::vector<rtc::ArrayView<float>>>* capture_sub_frame_view) {
105 FillSubFrameView(capture, sub_frame_index, capture_sub_frame_view);
106
107 if (linear_output) {
108 RTC_DCHECK(linear_output_framer);
109 RTC_DCHECK(linear_output_block);
110 RTC_DCHECK(linear_output_sub_frame_view);
111 FillSubFrameView(linear_output, sub_frame_index,
112 linear_output_sub_frame_view);
113 }
114
115 capture_blocker->InsertSubFrameAndExtractBlock(*capture_sub_frame_view,
116 capture_block);
peah69221db2017-01-27 03:28:19 -0800117 block_processor->ProcessCapture(level_change, saturated_microphone_signal,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100118 linear_output_block, capture_block);
119 output_framer->InsertBlockAndExtractSubFrame(*capture_block,
120 capture_sub_frame_view);
121
122 if (linear_output) {
123 RTC_DCHECK(linear_output_framer);
124 linear_output_framer->InsertBlockAndExtractSubFrame(
125 *linear_output_block, linear_output_sub_frame_view);
126 }
peahd0263542017-01-03 04:20:34 -0800127}
128
129void ProcessRemainingCaptureFrameContent(
peah69221db2017-01-27 03:28:19 -0800130 bool level_change,
peahd0263542017-01-03 04:20:34 -0800131 bool saturated_microphone_signal,
132 FrameBlocker* capture_blocker,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100133 BlockFramer* linear_output_framer,
peahd0263542017-01-03 04:20:34 -0800134 BlockFramer* output_framer,
135 BlockProcessor* block_processor,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100136 std::vector<std::vector<std::vector<float>>>* linear_output_block,
Per Åhgrence202a02019-09-02 17:01:19 +0200137 std::vector<std::vector<std::vector<float>>>* block) {
peahd0263542017-01-03 04:20:34 -0800138 if (!capture_blocker->IsBlockAvailable()) {
139 return;
140 }
141
142 capture_blocker->ExtractBlock(block);
peah69221db2017-01-27 03:28:19 -0800143 block_processor->ProcessCapture(level_change, saturated_microphone_signal,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100144 linear_output_block, block);
peahd0263542017-01-03 04:20:34 -0800145 output_framer->InsertBlock(*block);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100146
147 if (linear_output_framer) {
148 RTC_DCHECK(linear_output_block);
149 linear_output_framer->InsertBlock(*linear_output_block);
150 }
peahd0263542017-01-03 04:20:34 -0800151}
152
peahcf02cf12017-04-05 14:18:07 -0700153void BufferRenderFrameContent(
Per Åhgrence202a02019-09-02 17:01:19 +0200154 std::vector<std::vector<std::vector<float>>>* render_frame,
peahd0263542017-01-03 04:20:34 -0800155 size_t sub_frame_index,
156 FrameBlocker* render_blocker,
157 BlockProcessor* block_processor,
Per Åhgrence202a02019-09-02 17:01:19 +0200158 std::vector<std::vector<std::vector<float>>>* block,
159 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
peahd0263542017-01-03 04:20:34 -0800160 FillSubFrameView(render_frame, sub_frame_index, sub_frame_view);
161 render_blocker->InsertSubFrameAndExtractBlock(*sub_frame_view, block);
peahcf02cf12017-04-05 14:18:07 -0700162 block_processor->BufferRender(*block);
peahd0263542017-01-03 04:20:34 -0800163}
164
Per Åhgrence202a02019-09-02 17:01:19 +0200165void BufferRemainingRenderFrameContent(
166 FrameBlocker* render_blocker,
167 BlockProcessor* block_processor,
168 std::vector<std::vector<std::vector<float>>>* block) {
peahd0263542017-01-03 04:20:34 -0800169 if (!render_blocker->IsBlockAvailable()) {
peahcf02cf12017-04-05 14:18:07 -0700170 return;
peahd0263542017-01-03 04:20:34 -0800171 }
172 render_blocker->ExtractBlock(block);
peahcf02cf12017-04-05 14:18:07 -0700173 block_processor->BufferRender(*block);
peahd0263542017-01-03 04:20:34 -0800174}
175
Per Åhgren0aefbf02019-08-23 21:29:17 +0200176void CopyBufferIntoFrame(const AudioBuffer& buffer,
peahcf02cf12017-04-05 14:18:07 -0700177 size_t num_bands,
Per Åhgrence202a02019-09-02 17:01:19 +0200178 size_t num_channels,
179 std::vector<std::vector<std::vector<float>>>* frame) {
peahd0263542017-01-03 04:20:34 -0800180 RTC_DCHECK_EQ(num_bands, frame->size());
Per Åhgrence202a02019-09-02 17:01:19 +0200181 RTC_DCHECK_EQ(num_channels, (*frame)[0].size());
182 RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, (*frame)[0][0].size());
183 for (size_t band = 0; band < num_bands; ++band) {
184 for (size_t channel = 0; channel < num_channels; ++channel) {
185 rtc::ArrayView<const float> buffer_view(
186 &buffer.split_bands_const(channel)[band][0],
187 AudioBuffer::kSplitBandSize);
188 std::copy(buffer_view.begin(), buffer_view.end(),
189 (*frame)[band][channel].begin());
190 }
peahcf02cf12017-04-05 14:18:07 -0700191 }
peahd0263542017-01-03 04:20:34 -0800192}
193
peahd0263542017-01-03 04:20:34 -0800194} // namespace
195
196class EchoCanceller3::RenderWriter {
197 public:
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000198 RenderWriter(ApmDataDumper* data_dumper,
Per Åhgrence202a02019-09-02 17:01:19 +0200199 SwapQueue<std::vector<std::vector<std::vector<float>>>,
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000200 Aec3RenderQueueItemVerifier>* render_transfer_queue,
Per Åhgrence202a02019-09-02 17:01:19 +0200201 size_t num_bands,
202 size_t num_channels);
peahd0263542017-01-03 04:20:34 -0800203 ~RenderWriter();
Per Åhgren0aefbf02019-08-23 21:29:17 +0200204 void Insert(const AudioBuffer& input);
peahd0263542017-01-03 04:20:34 -0800205
206 private:
207 ApmDataDumper* data_dumper_;
Per Åhgrence202a02019-09-02 17:01:19 +0200208 const size_t num_bands_;
209 const size_t num_channels_;
Per Åhgren0aefbf02019-08-23 21:29:17 +0200210 HighPassFilter high_pass_filter_;
Per Åhgrence202a02019-09-02 17:01:19 +0200211 std::vector<std::vector<std::vector<float>>> render_queue_input_frame_;
212 SwapQueue<std::vector<std::vector<std::vector<float>>>,
213 Aec3RenderQueueItemVerifier>* render_transfer_queue_;
peahd0263542017-01-03 04:20:34 -0800214 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderWriter);
215};
216
217EchoCanceller3::RenderWriter::RenderWriter(
218 ApmDataDumper* data_dumper,
Per Åhgrence202a02019-09-02 17:01:19 +0200219 SwapQueue<std::vector<std::vector<std::vector<float>>>,
220 Aec3RenderQueueItemVerifier>* render_transfer_queue,
221 size_t num_bands,
222 size_t num_channels)
peahd0263542017-01-03 04:20:34 -0800223 : data_dumper_(data_dumper),
peahd0263542017-01-03 04:20:34 -0800224 num_bands_(num_bands),
Per Åhgrence202a02019-09-02 17:01:19 +0200225 num_channels_(num_channels),
226 high_pass_filter_(num_channels),
227 render_queue_input_frame_(
228 num_bands_,
229 std::vector<std::vector<float>>(
230 num_channels_,
231 std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
peahd0263542017-01-03 04:20:34 -0800232 render_transfer_queue_(render_transfer_queue) {
233 RTC_DCHECK(data_dumper);
234}
235
236EchoCanceller3::RenderWriter::~RenderWriter() = default;
237
Per Åhgren0aefbf02019-08-23 21:29:17 +0200238void EchoCanceller3::RenderWriter::Insert(const AudioBuffer& input) {
Per Åhgrence202a02019-09-02 17:01:19 +0200239 RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, input.num_frames_per_band());
Per Åhgren0aefbf02019-08-23 21:29:17 +0200240 RTC_DCHECK_EQ(num_bands_, input.num_bands());
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200241 RTC_DCHECK_EQ(num_channels_, input.num_channels());
Gustaf Ullberg7d042782018-01-16 13:39:27 +0100242
243 // TODO(bugs.webrtc.org/8759) Temporary work-around.
Per Åhgrence202a02019-09-02 17:01:19 +0200244 if (num_bands_ != input.num_bands())
Gustaf Ullberg7d042782018-01-16 13:39:27 +0100245 return;
246
Per Åhgrence202a02019-09-02 17:01:19 +0200247 data_dumper_->DumpWav("aec3_render_input", AudioBuffer::kSplitBandSize,
248 &input.split_bands_const(0)[0][0], 16000, 1);
peahd0263542017-01-03 04:20:34 -0800249
Per Åhgrence202a02019-09-02 17:01:19 +0200250 CopyBufferIntoFrame(input, num_bands_, num_channels_,
peahcf02cf12017-04-05 14:18:07 -0700251 &render_queue_input_frame_);
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200252 high_pass_filter_.Process(&render_queue_input_frame_[0]);
peahd0263542017-01-03 04:20:34 -0800253
peah925e9d72017-04-10 04:18:38 -0700254 static_cast<void>(render_transfer_queue_->Insert(&render_queue_input_frame_));
peahd0263542017-01-03 04:20:34 -0800255}
256
peahe0eae3c2016-12-14 01:16:23 -0800257int EchoCanceller3::instance_count_ = 0;
258
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200259EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config,
Per Åhgrence202a02019-09-02 17:01:19 +0200260 int sample_rate_hz,
261 size_t num_render_channels,
262 size_t num_capture_channels)
263 : EchoCanceller3(AdjustConfig(config),
264 sample_rate_hz,
265 num_render_channels,
266 num_capture_channels,
267 std::unique_ptr<BlockProcessor>(
268 BlockProcessor::Create(AdjustConfig(config),
269 sample_rate_hz,
270 num_render_channels,
271 num_capture_channels))) {}
Per Åhgren8ba58612017-12-01 23:01:44 +0100272EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config,
273 int sample_rate_hz,
Per Åhgrence202a02019-09-02 17:01:19 +0200274 size_t num_render_channels,
275 size_t num_capture_channels,
peahd0263542017-01-03 04:20:34 -0800276 std::unique_ptr<BlockProcessor> block_processor)
277 : data_dumper_(
278 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
Per Åhgren398689f2018-08-23 11:38:27 +0200279 config_(config),
peahd0263542017-01-03 04:20:34 -0800280 sample_rate_hz_(sample_rate_hz),
281 num_bands_(NumBandsForRate(sample_rate_hz_)),
Per Åhgrence202a02019-09-02 17:01:19 +0200282 num_render_channels_(num_render_channels),
283 num_capture_channels_(num_capture_channels),
284 output_framer_(num_bands_, num_capture_channels_),
285 capture_blocker_(num_bands_, num_capture_channels_),
286 render_blocker_(num_bands_, num_render_channels_),
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000287 render_transfer_queue_(
288 kRenderTransferQueueSizeFrames,
Per Åhgrence202a02019-09-02 17:01:19 +0200289 std::vector<std::vector<std::vector<float>>>(
Per Åhgrend112c752019-09-02 13:56:56 +0000290 num_bands_,
Per Åhgrence202a02019-09-02 17:01:19 +0200291 std::vector<std::vector<float>>(
292 num_render_channels_,
293 std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
294 Aec3RenderQueueItemVerifier(num_bands_,
295 num_render_channels_,
296 AudioBuffer::kSplitBandSize)),
Per Åhgrend112c752019-09-02 13:56:56 +0000297 block_processor_(std::move(block_processor)),
Per Åhgrence202a02019-09-02 17:01:19 +0200298 render_queue_output_frame_(
299 num_bands_,
300 std::vector<std::vector<float>>(
301 num_render_channels_,
302 std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
303 render_block_(
304 num_bands_,
305 std::vector<std::vector<float>>(num_render_channels_,
306 std::vector<float>(kBlockSize, 0.f))),
307 capture_block_(
308 num_bands_,
309 std::vector<std::vector<float>>(num_capture_channels_,
310 std::vector<float>(kBlockSize, 0.f))),
311 render_sub_frame_view_(
312 num_bands_,
313 std::vector<rtc::ArrayView<float>>(num_render_channels_)),
314 capture_sub_frame_view_(
315 num_bands_,
316 std::vector<rtc::ArrayView<float>>(num_capture_channels_)),
Per Åhgren398689f2018-08-23 11:38:27 +0200317 block_delay_buffer_(num_bands_,
Per Åhgrence202a02019-09-02 17:01:19 +0200318 AudioBuffer::kSplitBandSize,
Per Åhgren398689f2018-08-23 11:38:27 +0200319 config_.delay.fixed_capture_delay_samples) {
peah21920892017-02-08 05:08:56 -0800320 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
321
Per Åhgrence202a02019-09-02 17:01:19 +0200322 render_writer_.reset(new RenderWriter(data_dumper_.get(),
323 &render_transfer_queue_, num_bands_,
324 num_render_channels_));
peahd0263542017-01-03 04:20:34 -0800325
326 RTC_DCHECK_EQ(num_bands_, std::max(sample_rate_hz_, 16000) / 16000);
327 RTC_DCHECK_GE(kMaxNumBands, num_bands_);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100328
329 if (config_.filter.export_linear_aec_output) {
330 linear_output_framer_.reset(new BlockFramer(1, num_capture_channels_));
331 linear_output_block_ =
332 std::make_unique<std::vector<std::vector<std::vector<float>>>>(
333 1, std::vector<std::vector<float>>(
334 num_capture_channels_, std::vector<float>(kBlockSize, 0.f)));
335 linear_output_sub_frame_view_ =
336 std::vector<std::vector<rtc::ArrayView<float>>>(
337 1, std::vector<rtc::ArrayView<float>>(num_capture_channels_));
338 }
peahe0eae3c2016-12-14 01:16:23 -0800339}
340
341EchoCanceller3::~EchoCanceller3() = default;
342
Per Åhgren0aefbf02019-08-23 21:29:17 +0200343void EchoCanceller3::AnalyzeRender(const AudioBuffer& render) {
peahd0263542017-01-03 04:20:34 -0800344 RTC_DCHECK_RUNS_SERIALIZED(&render_race_checker_);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100345
Per Åhgrence202a02019-09-02 17:01:19 +0200346 RTC_DCHECK_EQ(render.num_channels(), num_render_channels_);
peahcf02cf12017-04-05 14:18:07 -0700347 data_dumper_->DumpRaw("aec3_call_order",
348 static_cast<int>(EchoCanceller3ApiCall::kRender));
349
peahd0263542017-01-03 04:20:34 -0800350 return render_writer_->Insert(render);
peahe0eae3c2016-12-14 01:16:23 -0800351}
352
Per Åhgren0aefbf02019-08-23 21:29:17 +0200353void EchoCanceller3::AnalyzeCapture(const AudioBuffer& capture) {
peahd0263542017-01-03 04:20:34 -0800354 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200355 data_dumper_->DumpWav("aec3_capture_analyze_input", capture.num_frames(),
356 capture.channels_const()[0], sample_rate_hz_, 1);
peahd0263542017-01-03 04:20:34 -0800357 saturated_microphone_signal_ = false;
Per Åhgrence202a02019-09-02 17:01:19 +0200358 for (size_t channel = 0; channel < capture.num_channels(); ++channel) {
peahd0263542017-01-03 04:20:34 -0800359 saturated_microphone_signal_ |=
Per Åhgren0aefbf02019-08-23 21:29:17 +0200360 DetectSaturation(rtc::ArrayView<const float>(
Per Åhgrence202a02019-09-02 17:01:19 +0200361 capture.channels_const()[channel], capture.num_frames()));
peahd0263542017-01-03 04:20:34 -0800362 if (saturated_microphone_signal_) {
363 break;
364 }
365 }
366}
peahe0eae3c2016-12-14 01:16:23 -0800367
peah69221db2017-01-27 03:28:19 -0800368void EchoCanceller3::ProcessCapture(AudioBuffer* capture, bool level_change) {
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100369 ProcessCapture(capture, nullptr, level_change);
370}
371
372void EchoCanceller3::ProcessCapture(AudioBuffer* capture,
373 AudioBuffer* linear_output,
374 bool level_change) {
peahd0263542017-01-03 04:20:34 -0800375 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
376 RTC_DCHECK(capture);
peahd0263542017-01-03 04:20:34 -0800377 RTC_DCHECK_EQ(num_bands_, capture->num_bands());
Per Åhgrence202a02019-09-02 17:01:19 +0200378 RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, capture->num_frames_per_band());
379 RTC_DCHECK_EQ(capture->num_channels(), num_capture_channels_);
peahcf02cf12017-04-05 14:18:07 -0700380 data_dumper_->DumpRaw("aec3_call_order",
381 static_cast<int>(EchoCanceller3ApiCall::kCapture));
peahd0263542017-01-03 04:20:34 -0800382
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100383 if (linear_output && !linear_output_framer_) {
384 RTC_LOG(LS_ERROR) << "Trying to retrieve the linear AEC output without "
385 "properly configuring AEC3.";
386 RTC_NOTREACHED();
387 }
388
Per Åhgren14f252a2018-11-27 18:02:56 +0100389 // Report capture call in the metrics and periodically update API call
390 // metrics.
391 api_call_metrics_.ReportCaptureCall();
392
Per Åhgren398689f2018-08-23 11:38:27 +0200393 // Optionally delay the capture signal.
394 if (config_.delay.fixed_capture_delay_samples > 0) {
395 block_delay_buffer_.DelaySignal(capture);
396 }
397
Per Åhgrence202a02019-09-02 17:01:19 +0200398 rtc::ArrayView<float> capture_lower_band = rtc::ArrayView<float>(
399 &capture->split_bands(0)[0][0], AudioBuffer::kSplitBandSize);
peahd0263542017-01-03 04:20:34 -0800400
Per Åhgrence202a02019-09-02 17:01:19 +0200401 data_dumper_->DumpWav("aec3_capture_input", capture_lower_band, 16000, 1);
peahd0263542017-01-03 04:20:34 -0800402
peahcf02cf12017-04-05 14:18:07 -0700403 EmptyRenderQueue();
peahd0263542017-01-03 04:20:34 -0800404
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100405 ProcessCaptureFrameContent(linear_output, capture, level_change,
Per Åhgrence202a02019-09-02 17:01:19 +0200406 saturated_microphone_signal_, 0, &capture_blocker_,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100407 linear_output_framer_.get(), &output_framer_,
408 block_processor_.get(), linear_output_block_.get(),
409 &linear_output_sub_frame_view_, &capture_block_,
410 &capture_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800411
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100412 ProcessCaptureFrameContent(linear_output, capture, level_change,
Per Åhgrence202a02019-09-02 17:01:19 +0200413 saturated_microphone_signal_, 1, &capture_blocker_,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100414 linear_output_framer_.get(), &output_framer_,
415 block_processor_.get(), linear_output_block_.get(),
416 &linear_output_sub_frame_view_, &capture_block_,
417 &capture_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800418
419 ProcessRemainingCaptureFrameContent(
peah69221db2017-01-27 03:28:19 -0800420 level_change, saturated_microphone_signal_, &capture_blocker_,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100421 linear_output_framer_.get(), &output_framer_, block_processor_.get(),
422 linear_output_block_.get(), &capture_block_);
peahd0263542017-01-03 04:20:34 -0800423
Per Åhgrence202a02019-09-02 17:01:19 +0200424 data_dumper_->DumpWav("aec3_capture_output", AudioBuffer::kSplitBandSize,
425 &capture->split_bands(0)[0][0], 16000, 1);
peahe0eae3c2016-12-14 01:16:23 -0800426}
427
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100428EchoControl::Metrics EchoCanceller3::GetMetrics() const {
429 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
430 Metrics metrics;
431 block_processor_->GetMetrics(&metrics);
432 return metrics;
433}
434
Gustaf Ullberg3cb61042019-10-24 15:52:10 +0200435void EchoCanceller3::SetAudioBufferDelay(int delay_ms) {
Per Åhgrend0fa8202018-04-18 09:35:13 +0200436 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
437 block_processor_->SetAudioBufferDelay(delay_ms);
438}
439
Gustaf Ullberg8675eee2019-10-09 13:34:36 +0200440bool EchoCanceller3::ActiveProcessing() const {
441 return true;
442}
443
peahcf02cf12017-04-05 14:18:07 -0700444void EchoCanceller3::EmptyRenderQueue() {
peahd0263542017-01-03 04:20:34 -0800445 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
peahd0263542017-01-03 04:20:34 -0800446 bool frame_to_buffer =
447 render_transfer_queue_.Remove(&render_queue_output_frame_);
448 while (frame_to_buffer) {
Per Åhgren14f252a2018-11-27 18:02:56 +0100449 // Report render call in the metrics.
450 api_call_metrics_.ReportRenderCall();
451
peahcf02cf12017-04-05 14:18:07 -0700452 BufferRenderFrameContent(&render_queue_output_frame_, 0, &render_blocker_,
Per Åhgrence202a02019-09-02 17:01:19 +0200453 block_processor_.get(), &render_block_,
454 &render_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800455
Per Åhgrence202a02019-09-02 17:01:19 +0200456 BufferRenderFrameContent(&render_queue_output_frame_, 1, &render_blocker_,
457 block_processor_.get(), &render_block_,
458 &render_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800459
peahcf02cf12017-04-05 14:18:07 -0700460 BufferRemainingRenderFrameContent(&render_blocker_, block_processor_.get(),
Per Åhgrence202a02019-09-02 17:01:19 +0200461 &render_block_);
peahd0263542017-01-03 04:20:34 -0800462
463 frame_to_buffer =
464 render_transfer_queue_.Remove(&render_queue_output_frame_);
465 }
peahd0263542017-01-03 04:20:34 -0800466}
peahe0eae3c2016-12-14 01:16:23 -0800467} // namespace webrtc