blob: a7a76d35d9000bbd2c862fc2e1abf8c6890c4d3b [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"
Gustaf Ullberg9249fbf2019-03-14 11:24:54 +010019#include "system_wrappers/include/field_trial.h"
peahe0eae3c2016-12-14 01:16:23 -080020
21namespace webrtc {
22
peahd0263542017-01-03 04:20:34 -080023namespace {
24
peahcf02cf12017-04-05 14:18:07 -070025enum class EchoCanceller3ApiCall { kCapture, kRender };
26
peahd0263542017-01-03 04:20:34 -080027bool DetectSaturation(rtc::ArrayView<const float> y) {
28 for (auto y_k : y) {
peah522d71b2017-02-23 05:16:26 -080029 if (y_k >= 32700.0f || y_k <= -32700.0f) {
peahd0263542017-01-03 04:20:34 -080030 return true;
31 }
32 }
33 return false;
34}
35
Per Åhgren251c7352018-03-28 16:31:57 +020036// Method for adjusting config parameter dependencies..
37EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) {
38 EchoCanceller3Config adjusted_cfg = config;
Gustaf Ullberg9249fbf2019-03-14 11:24:54 +010039
40 if (field_trial::IsEnabled("WebRTC-Aec3ShortHeadroomKillSwitch")) {
41 // Two blocks headroom.
42 adjusted_cfg.delay.delay_headroom_samples = kBlockSize * 2;
43 }
44
Per Åhgren8be669f2019-10-11 23:02:26 +020045 if (field_trial::IsEnabled("WebRTC-Aec3ClampInstQualityToZeroKillSwitch")) {
46 adjusted_cfg.erle.clamp_quality_estimate_to_zero = false;
47 }
48
49 if (field_trial::IsEnabled("WebRTC-Aec3ClampInstQualityToOneKillSwitch")) {
50 adjusted_cfg.erle.clamp_quality_estimate_to_one = false;
51 }
52
Per Åhgren251c7352018-03-28 16:31:57 +020053 return adjusted_cfg;
54}
55
Per Åhgrence202a02019-09-02 17:01:19 +020056void FillSubFrameView(
57 AudioBuffer* frame,
58 size_t sub_frame_index,
59 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
peahd0263542017-01-03 04:20:34 -080060 RTC_DCHECK_GE(1, sub_frame_index);
61 RTC_DCHECK_LE(0, sub_frame_index);
62 RTC_DCHECK_EQ(frame->num_bands(), sub_frame_view->size());
Per Åhgrence202a02019-09-02 17:01:19 +020063 RTC_DCHECK_EQ(frame->num_channels(), (*sub_frame_view)[0].size());
64 for (size_t band = 0; band < sub_frame_view->size(); ++band) {
65 for (size_t channel = 0; channel < (*sub_frame_view)[0].size(); ++channel) {
66 (*sub_frame_view)[band][channel] = rtc::ArrayView<float>(
67 &frame->split_bands(channel)[band][sub_frame_index * kSubFrameLength],
68 kSubFrameLength);
69 }
peahd0263542017-01-03 04:20:34 -080070 }
71}
72
Per Åhgrence202a02019-09-02 17:01:19 +020073void FillSubFrameView(
74 std::vector<std::vector<std::vector<float>>>* frame,
75 size_t sub_frame_index,
76 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
peahd0263542017-01-03 04:20:34 -080077 RTC_DCHECK_GE(1, sub_frame_index);
78 RTC_DCHECK_EQ(frame->size(), sub_frame_view->size());
Per Åhgrence202a02019-09-02 17:01:19 +020079 RTC_DCHECK_EQ((*frame)[0].size(), (*sub_frame_view)[0].size());
80 for (size_t band = 0; band < frame->size(); ++band) {
81 for (size_t channel = 0; channel < (*frame)[band].size(); ++channel) {
82 (*sub_frame_view)[band][channel] = rtc::ArrayView<float>(
83 &(*frame)[band][channel][sub_frame_index * kSubFrameLength],
84 kSubFrameLength);
85 }
peahd0263542017-01-03 04:20:34 -080086 }
87}
88
89void ProcessCaptureFrameContent(
90 AudioBuffer* capture,
peah69221db2017-01-27 03:28:19 -080091 bool level_change,
peahd0263542017-01-03 04:20:34 -080092 bool saturated_microphone_signal,
93 size_t sub_frame_index,
94 FrameBlocker* capture_blocker,
95 BlockFramer* output_framer,
96 BlockProcessor* block_processor,
Per Åhgrence202a02019-09-02 17:01:19 +020097 std::vector<std::vector<std::vector<float>>>* block,
98 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
peahd0263542017-01-03 04:20:34 -080099 FillSubFrameView(capture, sub_frame_index, sub_frame_view);
100 capture_blocker->InsertSubFrameAndExtractBlock(*sub_frame_view, block);
peah69221db2017-01-27 03:28:19 -0800101 block_processor->ProcessCapture(level_change, saturated_microphone_signal,
102 block);
peahd0263542017-01-03 04:20:34 -0800103 output_framer->InsertBlockAndExtractSubFrame(*block, sub_frame_view);
104}
105
106void ProcessRemainingCaptureFrameContent(
peah69221db2017-01-27 03:28:19 -0800107 bool level_change,
peahd0263542017-01-03 04:20:34 -0800108 bool saturated_microphone_signal,
109 FrameBlocker* capture_blocker,
110 BlockFramer* output_framer,
111 BlockProcessor* block_processor,
Per Åhgrence202a02019-09-02 17:01:19 +0200112 std::vector<std::vector<std::vector<float>>>* block) {
peahd0263542017-01-03 04:20:34 -0800113 if (!capture_blocker->IsBlockAvailable()) {
114 return;
115 }
116
117 capture_blocker->ExtractBlock(block);
peah69221db2017-01-27 03:28:19 -0800118 block_processor->ProcessCapture(level_change, saturated_microphone_signal,
119 block);
peahd0263542017-01-03 04:20:34 -0800120 output_framer->InsertBlock(*block);
121}
122
peahcf02cf12017-04-05 14:18:07 -0700123void BufferRenderFrameContent(
Per Åhgrence202a02019-09-02 17:01:19 +0200124 std::vector<std::vector<std::vector<float>>>* render_frame,
peahd0263542017-01-03 04:20:34 -0800125 size_t sub_frame_index,
126 FrameBlocker* render_blocker,
127 BlockProcessor* block_processor,
Per Åhgrence202a02019-09-02 17:01:19 +0200128 std::vector<std::vector<std::vector<float>>>* block,
129 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
peahd0263542017-01-03 04:20:34 -0800130 FillSubFrameView(render_frame, sub_frame_index, sub_frame_view);
131 render_blocker->InsertSubFrameAndExtractBlock(*sub_frame_view, block);
peahcf02cf12017-04-05 14:18:07 -0700132 block_processor->BufferRender(*block);
peahd0263542017-01-03 04:20:34 -0800133}
134
Per Åhgrence202a02019-09-02 17:01:19 +0200135void BufferRemainingRenderFrameContent(
136 FrameBlocker* render_blocker,
137 BlockProcessor* block_processor,
138 std::vector<std::vector<std::vector<float>>>* block) {
peahd0263542017-01-03 04:20:34 -0800139 if (!render_blocker->IsBlockAvailable()) {
peahcf02cf12017-04-05 14:18:07 -0700140 return;
peahd0263542017-01-03 04:20:34 -0800141 }
142 render_blocker->ExtractBlock(block);
peahcf02cf12017-04-05 14:18:07 -0700143 block_processor->BufferRender(*block);
peahd0263542017-01-03 04:20:34 -0800144}
145
Per Åhgren0aefbf02019-08-23 21:29:17 +0200146void CopyBufferIntoFrame(const AudioBuffer& buffer,
peahcf02cf12017-04-05 14:18:07 -0700147 size_t num_bands,
Per Åhgrence202a02019-09-02 17:01:19 +0200148 size_t num_channels,
149 std::vector<std::vector<std::vector<float>>>* frame) {
peahd0263542017-01-03 04:20:34 -0800150 RTC_DCHECK_EQ(num_bands, frame->size());
Per Åhgrence202a02019-09-02 17:01:19 +0200151 RTC_DCHECK_EQ(num_channels, (*frame)[0].size());
152 RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, (*frame)[0][0].size());
153 for (size_t band = 0; band < num_bands; ++band) {
154 for (size_t channel = 0; channel < num_channels; ++channel) {
155 rtc::ArrayView<const float> buffer_view(
156 &buffer.split_bands_const(channel)[band][0],
157 AudioBuffer::kSplitBandSize);
158 std::copy(buffer_view.begin(), buffer_view.end(),
159 (*frame)[band][channel].begin());
160 }
peahcf02cf12017-04-05 14:18:07 -0700161 }
peahd0263542017-01-03 04:20:34 -0800162}
163
peahd0263542017-01-03 04:20:34 -0800164} // namespace
165
166class EchoCanceller3::RenderWriter {
167 public:
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000168 RenderWriter(ApmDataDumper* data_dumper,
Per Åhgrence202a02019-09-02 17:01:19 +0200169 SwapQueue<std::vector<std::vector<std::vector<float>>>,
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000170 Aec3RenderQueueItemVerifier>* render_transfer_queue,
Per Åhgrence202a02019-09-02 17:01:19 +0200171 size_t num_bands,
172 size_t num_channels);
peahd0263542017-01-03 04:20:34 -0800173 ~RenderWriter();
Per Åhgren0aefbf02019-08-23 21:29:17 +0200174 void Insert(const AudioBuffer& input);
peahd0263542017-01-03 04:20:34 -0800175
176 private:
177 ApmDataDumper* data_dumper_;
Per Åhgrence202a02019-09-02 17:01:19 +0200178 const size_t num_bands_;
179 const size_t num_channels_;
Per Åhgren0aefbf02019-08-23 21:29:17 +0200180 HighPassFilter high_pass_filter_;
Per Åhgrence202a02019-09-02 17:01:19 +0200181 std::vector<std::vector<std::vector<float>>> render_queue_input_frame_;
182 SwapQueue<std::vector<std::vector<std::vector<float>>>,
183 Aec3RenderQueueItemVerifier>* render_transfer_queue_;
peahd0263542017-01-03 04:20:34 -0800184 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderWriter);
185};
186
187EchoCanceller3::RenderWriter::RenderWriter(
188 ApmDataDumper* data_dumper,
Per Åhgrence202a02019-09-02 17:01:19 +0200189 SwapQueue<std::vector<std::vector<std::vector<float>>>,
190 Aec3RenderQueueItemVerifier>* render_transfer_queue,
191 size_t num_bands,
192 size_t num_channels)
peahd0263542017-01-03 04:20:34 -0800193 : data_dumper_(data_dumper),
peahd0263542017-01-03 04:20:34 -0800194 num_bands_(num_bands),
Per Åhgrence202a02019-09-02 17:01:19 +0200195 num_channels_(num_channels),
196 high_pass_filter_(num_channels),
197 render_queue_input_frame_(
198 num_bands_,
199 std::vector<std::vector<float>>(
200 num_channels_,
201 std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
peahd0263542017-01-03 04:20:34 -0800202 render_transfer_queue_(render_transfer_queue) {
203 RTC_DCHECK(data_dumper);
204}
205
206EchoCanceller3::RenderWriter::~RenderWriter() = default;
207
Per Åhgren0aefbf02019-08-23 21:29:17 +0200208void EchoCanceller3::RenderWriter::Insert(const AudioBuffer& input) {
Per Åhgrence202a02019-09-02 17:01:19 +0200209 RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, input.num_frames_per_band());
Per Åhgren0aefbf02019-08-23 21:29:17 +0200210 RTC_DCHECK_EQ(num_bands_, input.num_bands());
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200211 RTC_DCHECK_EQ(num_channels_, input.num_channels());
Gustaf Ullberg7d042782018-01-16 13:39:27 +0100212
213 // TODO(bugs.webrtc.org/8759) Temporary work-around.
Per Åhgrence202a02019-09-02 17:01:19 +0200214 if (num_bands_ != input.num_bands())
Gustaf Ullberg7d042782018-01-16 13:39:27 +0100215 return;
216
Per Åhgrence202a02019-09-02 17:01:19 +0200217 data_dumper_->DumpWav("aec3_render_input", AudioBuffer::kSplitBandSize,
218 &input.split_bands_const(0)[0][0], 16000, 1);
peahd0263542017-01-03 04:20:34 -0800219
Per Åhgrence202a02019-09-02 17:01:19 +0200220 CopyBufferIntoFrame(input, num_bands_, num_channels_,
peahcf02cf12017-04-05 14:18:07 -0700221 &render_queue_input_frame_);
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200222 high_pass_filter_.Process(&render_queue_input_frame_[0]);
peahd0263542017-01-03 04:20:34 -0800223
peah925e9d72017-04-10 04:18:38 -0700224 static_cast<void>(render_transfer_queue_->Insert(&render_queue_input_frame_));
peahd0263542017-01-03 04:20:34 -0800225}
226
peahe0eae3c2016-12-14 01:16:23 -0800227int EchoCanceller3::instance_count_ = 0;
228
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200229EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config,
Per Åhgrence202a02019-09-02 17:01:19 +0200230 int sample_rate_hz,
231 size_t num_render_channels,
232 size_t num_capture_channels)
233 : EchoCanceller3(AdjustConfig(config),
234 sample_rate_hz,
235 num_render_channels,
236 num_capture_channels,
237 std::unique_ptr<BlockProcessor>(
238 BlockProcessor::Create(AdjustConfig(config),
239 sample_rate_hz,
240 num_render_channels,
241 num_capture_channels))) {}
Per Åhgren8ba58612017-12-01 23:01:44 +0100242EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config,
243 int sample_rate_hz,
Per Åhgrence202a02019-09-02 17:01:19 +0200244 size_t num_render_channels,
245 size_t num_capture_channels,
peahd0263542017-01-03 04:20:34 -0800246 std::unique_ptr<BlockProcessor> block_processor)
247 : data_dumper_(
248 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
Per Åhgren398689f2018-08-23 11:38:27 +0200249 config_(config),
peahd0263542017-01-03 04:20:34 -0800250 sample_rate_hz_(sample_rate_hz),
251 num_bands_(NumBandsForRate(sample_rate_hz_)),
Per Åhgrence202a02019-09-02 17:01:19 +0200252 num_render_channels_(num_render_channels),
253 num_capture_channels_(num_capture_channels),
254 output_framer_(num_bands_, num_capture_channels_),
255 capture_blocker_(num_bands_, num_capture_channels_),
256 render_blocker_(num_bands_, num_render_channels_),
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000257 render_transfer_queue_(
258 kRenderTransferQueueSizeFrames,
Per Åhgrence202a02019-09-02 17:01:19 +0200259 std::vector<std::vector<std::vector<float>>>(
Per Åhgrend112c752019-09-02 13:56:56 +0000260 num_bands_,
Per Åhgrence202a02019-09-02 17:01:19 +0200261 std::vector<std::vector<float>>(
262 num_render_channels_,
263 std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
264 Aec3RenderQueueItemVerifier(num_bands_,
265 num_render_channels_,
266 AudioBuffer::kSplitBandSize)),
Per Åhgrend112c752019-09-02 13:56:56 +0000267 block_processor_(std::move(block_processor)),
Per Åhgrence202a02019-09-02 17:01:19 +0200268 render_queue_output_frame_(
269 num_bands_,
270 std::vector<std::vector<float>>(
271 num_render_channels_,
272 std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
273 render_block_(
274 num_bands_,
275 std::vector<std::vector<float>>(num_render_channels_,
276 std::vector<float>(kBlockSize, 0.f))),
277 capture_block_(
278 num_bands_,
279 std::vector<std::vector<float>>(num_capture_channels_,
280 std::vector<float>(kBlockSize, 0.f))),
281 render_sub_frame_view_(
282 num_bands_,
283 std::vector<rtc::ArrayView<float>>(num_render_channels_)),
284 capture_sub_frame_view_(
285 num_bands_,
286 std::vector<rtc::ArrayView<float>>(num_capture_channels_)),
Per Åhgren398689f2018-08-23 11:38:27 +0200287 block_delay_buffer_(num_bands_,
Per Åhgrence202a02019-09-02 17:01:19 +0200288 AudioBuffer::kSplitBandSize,
Per Åhgren398689f2018-08-23 11:38:27 +0200289 config_.delay.fixed_capture_delay_samples) {
peah21920892017-02-08 05:08:56 -0800290 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
291
Per Åhgrence202a02019-09-02 17:01:19 +0200292 render_writer_.reset(new RenderWriter(data_dumper_.get(),
293 &render_transfer_queue_, num_bands_,
294 num_render_channels_));
peahd0263542017-01-03 04:20:34 -0800295
296 RTC_DCHECK_EQ(num_bands_, std::max(sample_rate_hz_, 16000) / 16000);
297 RTC_DCHECK_GE(kMaxNumBands, num_bands_);
peahe0eae3c2016-12-14 01:16:23 -0800298}
299
300EchoCanceller3::~EchoCanceller3() = default;
301
Per Åhgren0aefbf02019-08-23 21:29:17 +0200302void EchoCanceller3::AnalyzeRender(const AudioBuffer& render) {
peahd0263542017-01-03 04:20:34 -0800303 RTC_DCHECK_RUNS_SERIALIZED(&render_race_checker_);
Per Åhgrence202a02019-09-02 17:01:19 +0200304 RTC_DCHECK_EQ(render.num_channels(), num_render_channels_);
peahcf02cf12017-04-05 14:18:07 -0700305 data_dumper_->DumpRaw("aec3_call_order",
306 static_cast<int>(EchoCanceller3ApiCall::kRender));
307
peahd0263542017-01-03 04:20:34 -0800308 return render_writer_->Insert(render);
peahe0eae3c2016-12-14 01:16:23 -0800309}
310
Per Åhgren0aefbf02019-08-23 21:29:17 +0200311void EchoCanceller3::AnalyzeCapture(const AudioBuffer& capture) {
peahd0263542017-01-03 04:20:34 -0800312 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200313 data_dumper_->DumpWav("aec3_capture_analyze_input", capture.num_frames(),
314 capture.channels_const()[0], sample_rate_hz_, 1);
peahd0263542017-01-03 04:20:34 -0800315
316 saturated_microphone_signal_ = false;
Per Åhgrence202a02019-09-02 17:01:19 +0200317 for (size_t channel = 0; channel < capture.num_channels(); ++channel) {
peahd0263542017-01-03 04:20:34 -0800318 saturated_microphone_signal_ |=
Per Åhgren0aefbf02019-08-23 21:29:17 +0200319 DetectSaturation(rtc::ArrayView<const float>(
Per Åhgrence202a02019-09-02 17:01:19 +0200320 capture.channels_const()[channel], capture.num_frames()));
peahd0263542017-01-03 04:20:34 -0800321 if (saturated_microphone_signal_) {
322 break;
323 }
324 }
325}
peahe0eae3c2016-12-14 01:16:23 -0800326
peah69221db2017-01-27 03:28:19 -0800327void EchoCanceller3::ProcessCapture(AudioBuffer* capture, bool level_change) {
peahd0263542017-01-03 04:20:34 -0800328 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
329 RTC_DCHECK(capture);
peahd0263542017-01-03 04:20:34 -0800330 RTC_DCHECK_EQ(num_bands_, capture->num_bands());
Per Åhgrence202a02019-09-02 17:01:19 +0200331 RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, capture->num_frames_per_band());
332 RTC_DCHECK_EQ(capture->num_channels(), num_capture_channels_);
peahcf02cf12017-04-05 14:18:07 -0700333 data_dumper_->DumpRaw("aec3_call_order",
334 static_cast<int>(EchoCanceller3ApiCall::kCapture));
peahd0263542017-01-03 04:20:34 -0800335
Per Åhgren14f252a2018-11-27 18:02:56 +0100336 // Report capture call in the metrics and periodically update API call
337 // metrics.
338 api_call_metrics_.ReportCaptureCall();
339
Per Åhgren398689f2018-08-23 11:38:27 +0200340 // Optionally delay the capture signal.
341 if (config_.delay.fixed_capture_delay_samples > 0) {
342 block_delay_buffer_.DelaySignal(capture);
343 }
344
Per Åhgrence202a02019-09-02 17:01:19 +0200345 rtc::ArrayView<float> capture_lower_band = rtc::ArrayView<float>(
346 &capture->split_bands(0)[0][0], AudioBuffer::kSplitBandSize);
peahd0263542017-01-03 04:20:34 -0800347
Per Åhgrence202a02019-09-02 17:01:19 +0200348 data_dumper_->DumpWav("aec3_capture_input", capture_lower_band, 16000, 1);
peahd0263542017-01-03 04:20:34 -0800349
peahcf02cf12017-04-05 14:18:07 -0700350 EmptyRenderQueue();
peahd0263542017-01-03 04:20:34 -0800351
Per Åhgrence202a02019-09-02 17:01:19 +0200352 ProcessCaptureFrameContent(capture, level_change,
353 saturated_microphone_signal_, 0, &capture_blocker_,
354 &output_framer_, block_processor_.get(),
355 &capture_block_, &capture_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800356
Per Åhgrence202a02019-09-02 17:01:19 +0200357 ProcessCaptureFrameContent(capture, level_change,
358 saturated_microphone_signal_, 1, &capture_blocker_,
359 &output_framer_, block_processor_.get(),
360 &capture_block_, &capture_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800361
362 ProcessRemainingCaptureFrameContent(
peah69221db2017-01-27 03:28:19 -0800363 level_change, saturated_microphone_signal_, &capture_blocker_,
Per Åhgrence202a02019-09-02 17:01:19 +0200364 &output_framer_, block_processor_.get(), &capture_block_);
peahd0263542017-01-03 04:20:34 -0800365
Per Åhgrence202a02019-09-02 17:01:19 +0200366 data_dumper_->DumpWav("aec3_capture_output", AudioBuffer::kSplitBandSize,
367 &capture->split_bands(0)[0][0], 16000, 1);
peahe0eae3c2016-12-14 01:16:23 -0800368}
369
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100370EchoControl::Metrics EchoCanceller3::GetMetrics() const {
371 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
372 Metrics metrics;
373 block_processor_->GetMetrics(&metrics);
374 return metrics;
375}
376
Per Åhgrend0fa8202018-04-18 09:35:13 +0200377void EchoCanceller3::SetAudioBufferDelay(size_t delay_ms) {
378 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
379 block_processor_->SetAudioBufferDelay(delay_ms);
380}
381
Gustaf Ullberg8675eee2019-10-09 13:34:36 +0200382bool EchoCanceller3::ActiveProcessing() const {
383 return true;
384}
385
peahcf02cf12017-04-05 14:18:07 -0700386void EchoCanceller3::EmptyRenderQueue() {
peahd0263542017-01-03 04:20:34 -0800387 RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
peahd0263542017-01-03 04:20:34 -0800388 bool frame_to_buffer =
389 render_transfer_queue_.Remove(&render_queue_output_frame_);
390 while (frame_to_buffer) {
Per Åhgren14f252a2018-11-27 18:02:56 +0100391 // Report render call in the metrics.
392 api_call_metrics_.ReportRenderCall();
393
peahcf02cf12017-04-05 14:18:07 -0700394 BufferRenderFrameContent(&render_queue_output_frame_, 0, &render_blocker_,
Per Åhgrence202a02019-09-02 17:01:19 +0200395 block_processor_.get(), &render_block_,
396 &render_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800397
Per Åhgrence202a02019-09-02 17:01:19 +0200398 BufferRenderFrameContent(&render_queue_output_frame_, 1, &render_blocker_,
399 block_processor_.get(), &render_block_,
400 &render_sub_frame_view_);
peahd0263542017-01-03 04:20:34 -0800401
peahcf02cf12017-04-05 14:18:07 -0700402 BufferRemainingRenderFrameContent(&render_blocker_, block_processor_.get(),
Per Åhgrence202a02019-09-02 17:01:19 +0200403 &render_block_);
peahd0263542017-01-03 04:20:34 -0800404
405 frame_to_buffer =
406 render_transfer_queue_.Remove(&render_queue_output_frame_);
407 }
peahd0263542017-01-03 04:20:34 -0800408}
peahe0eae3c2016-12-14 01:16:23 -0800409} // namespace webrtc