blob: 590380f897425402cc5e5b7258a7958e04493aa4 [file] [log] [blame]
peahd0263542017-01-03 04:20:34 -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/block_processor.h"
peahd0263542017-01-03 04:20:34 -080011
Yves Gerey988cc082018-10-23 12:03:01 +020012#include <utility>
13
Danil Chapovalovdb9f7ab2018-06-19 10:50:11 +020014#include "absl/types/optional.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "modules/audio_processing/aec3/aec3_common.h"
16#include "modules/audio_processing/aec3/block_processor_metrics.h"
Yves Gerey988cc082018-10-23 12:03:01 +020017#include "modules/audio_processing/aec3/delay_estimate.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "modules/audio_processing/aec3/echo_path_variability.h"
19#include "modules/audio_processing/logging/apm_data_dumper.h"
20#include "rtc_base/atomicops.h"
Yves Gerey988cc082018-10-23 12:03:01 +020021#include "rtc_base/checks.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/constructormagic.h"
Per Åhgrenfe9f2222017-09-26 23:33:26 +020023#include "rtc_base/logging.h"
peahd0263542017-01-03 04:20:34 -080024
25namespace webrtc {
26namespace {
27
peahcf02cf12017-04-05 14:18:07 -070028enum class BlockProcessorApiCall { kCapture, kRender };
29
peahd0263542017-01-03 04:20:34 -080030class BlockProcessorImpl final : public BlockProcessor {
31 public:
Per Åhgren8ba58612017-12-01 23:01:44 +010032 BlockProcessorImpl(const EchoCanceller3Config& config,
33 int sample_rate_hz,
peah69221db2017-01-27 03:28:19 -080034 std::unique_ptr<RenderDelayBuffer> render_buffer,
35 std::unique_ptr<RenderDelayController> delay_controller,
36 std::unique_ptr<EchoRemover> echo_remover);
37
peahd0263542017-01-03 04:20:34 -080038 ~BlockProcessorImpl() override;
39
peah69221db2017-01-27 03:28:19 -080040 void ProcessCapture(bool echo_path_gain_change,
41 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080042 std::vector<std::vector<float>>* capture_block) override;
43
peahcf02cf12017-04-05 14:18:07 -070044 void BufferRender(const std::vector<std::vector<float>>& block) override;
peahd0263542017-01-03 04:20:34 -080045
peah69221db2017-01-27 03:28:19 -080046 void UpdateEchoLeakageStatus(bool leakage_detected) override;
peahd0263542017-01-03 04:20:34 -080047
Gustaf Ullberg332150d2017-11-22 14:17:39 +010048 void GetMetrics(EchoControl::Metrics* metrics) const override;
49
Per Åhgrend0fa8202018-04-18 09:35:13 +020050 void SetAudioBufferDelay(size_t delay_ms) override;
51
peahd0263542017-01-03 04:20:34 -080052 private:
peahd0263542017-01-03 04:20:34 -080053 static int instance_count_;
54 std::unique_ptr<ApmDataDumper> data_dumper_;
Per Åhgren8ba58612017-12-01 23:01:44 +010055 const EchoCanceller3Config config_;
56 bool capture_properly_started_ = false;
57 bool render_properly_started_ = false;
peah69221db2017-01-27 03:28:19 -080058 const size_t sample_rate_hz_;
59 std::unique_ptr<RenderDelayBuffer> render_buffer_;
60 std::unique_ptr<RenderDelayController> delay_controller_;
61 std::unique_ptr<EchoRemover> echo_remover_;
peahe985b3f2017-02-28 22:08:53 -080062 BlockProcessorMetrics metrics_;
Per Åhgren8ba58612017-12-01 23:01:44 +010063 RenderDelayBuffer::BufferingEvent render_event_;
Per Åhgrenc59a5762017-12-11 21:34:19 +010064 size_t capture_call_counter_ = 0;
Danil Chapovalovdb9f7ab2018-06-19 10:50:11 +020065 absl::optional<DelayEstimate> estimated_delay_;
66 absl::optional<int> echo_remover_delay_;
peahd0263542017-01-03 04:20:34 -080067 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BlockProcessorImpl);
68};
69
70int BlockProcessorImpl::instance_count_ = 0;
71
peah69221db2017-01-27 03:28:19 -080072BlockProcessorImpl::BlockProcessorImpl(
Per Åhgren8ba58612017-12-01 23:01:44 +010073 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -080074 int sample_rate_hz,
75 std::unique_ptr<RenderDelayBuffer> render_buffer,
76 std::unique_ptr<RenderDelayController> delay_controller,
77 std::unique_ptr<EchoRemover> echo_remover)
78 : data_dumper_(
79 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
Per Åhgren8ba58612017-12-01 23:01:44 +010080 config_(config),
peah69221db2017-01-27 03:28:19 -080081 sample_rate_hz_(sample_rate_hz),
82 render_buffer_(std::move(render_buffer)),
83 delay_controller_(std::move(delay_controller)),
Per Åhgren8ba58612017-12-01 23:01:44 +010084 echo_remover_(std::move(echo_remover)),
85 render_event_(RenderDelayBuffer::BufferingEvent::kNone) {
peah21920892017-02-08 05:08:56 -080086 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
87}
peahd0263542017-01-03 04:20:34 -080088
89BlockProcessorImpl::~BlockProcessorImpl() = default;
90
91void BlockProcessorImpl::ProcessCapture(
peah69221db2017-01-27 03:28:19 -080092 bool echo_path_gain_change,
93 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080094 std::vector<std::vector<float>>* capture_block) {
95 RTC_DCHECK(capture_block);
96 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), capture_block->size());
97 RTC_DCHECK_EQ(kBlockSize, (*capture_block)[0].size());
Per Åhgrenc59a5762017-12-11 21:34:19 +010098
99 capture_call_counter_++;
100
peahcf02cf12017-04-05 14:18:07 -0700101 data_dumper_->DumpRaw("aec3_processblock_call_order",
102 static_cast<int>(BlockProcessorApiCall::kCapture));
103 data_dumper_->DumpWav("aec3_processblock_capture_input", kBlockSize,
104 &(*capture_block)[0][0],
105 LowestBandRate(sample_rate_hz_), 1);
peah69221db2017-01-27 03:28:19 -0800106
Per Åhgren8ba58612017-12-01 23:01:44 +0100107 if (render_properly_started_) {
108 if (!capture_properly_started_) {
109 capture_properly_started_ = true;
110 render_buffer_->Reset();
Per Åhgren8b7d2062018-10-30 23:44:40 +0100111 delay_controller_->Reset(true);
Per Åhgren8ba58612017-12-01 23:01:44 +0100112 }
113 } else {
114 // If no render data has yet arrived, do not process the capture signal.
peahcf02cf12017-04-05 14:18:07 -0700115 return;
peah69221db2017-01-27 03:28:19 -0800116 }
117
Per Åhgren8ba58612017-12-01 23:01:44 +0100118 EchoPathVariability echo_path_variability(
119 echo_path_gain_change, EchoPathVariability::DelayAdjustment::kNone,
120 false);
121
122 if (render_event_ == RenderDelayBuffer::BufferingEvent::kRenderOverrun &&
123 render_properly_started_) {
124 echo_path_variability.delay_change =
125 EchoPathVariability::DelayAdjustment::kBufferFlush;
Per Åhgren8b7d2062018-10-30 23:44:40 +0100126 delay_controller_->Reset(true);
Per Åhgrenc59a5762017-12-11 21:34:19 +0100127 RTC_LOG(LS_WARNING) << "Reset due to render buffer overrun at block "
128 << capture_call_counter_;
Per Åhgren8ba58612017-12-01 23:01:44 +0100129 }
130
131 // Update the render buffers with any newly arrived render blocks and prepare
132 // the render buffers for reading the render data corresponding to the current
133 // capture block.
Per Åhgrenc59a5762017-12-11 21:34:19 +0100134 render_event_ = render_buffer_->PrepareCaptureProcessing();
Per Åhgren8ba58612017-12-01 23:01:44 +0100135 RTC_DCHECK(RenderDelayBuffer::BufferingEvent::kRenderOverrun !=
136 render_event_);
137 if (render_event_ == RenderDelayBuffer::BufferingEvent::kRenderUnderrun) {
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100138 if (estimated_delay_ &&
139 estimated_delay_->quality == DelayEstimate::Quality::kRefined) {
140 echo_path_variability.delay_change =
141 EchoPathVariability::DelayAdjustment::kDelayReset;
Per Åhgren8b7d2062018-10-30 23:44:40 +0100142 delay_controller_->Reset(true);
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100143 capture_properly_started_ = false;
144 render_properly_started_ = false;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100145
Gustaf Ullberg11539f02018-10-15 13:40:29 +0200146 RTC_LOG(LS_WARNING) << "Reset due to render buffer underrun at block "
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100147 << capture_call_counter_;
148 }
Per Åhgren8ba58612017-12-01 23:01:44 +0100149 } else if (render_event_ == RenderDelayBuffer::BufferingEvent::kApiCallSkew) {
150 // There have been too many render calls in a row. Reset to avoid noncausal
151 // echo.
152 echo_path_variability.delay_change =
153 EchoPathVariability::DelayAdjustment::kDelayReset;
Per Åhgren8b7d2062018-10-30 23:44:40 +0100154 delay_controller_->Reset(true);
Per Åhgren8ba58612017-12-01 23:01:44 +0100155 capture_properly_started_ = false;
156 render_properly_started_ = false;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100157 RTC_LOG(LS_WARNING) << "Reset due to render buffer api skew at block "
158 << capture_call_counter_;
Per Åhgren8ba58612017-12-01 23:01:44 +0100159 }
160
peahcf02cf12017-04-05 14:18:07 -0700161 data_dumper_->DumpWav("aec3_processblock_capture_input2", kBlockSize,
162 &(*capture_block)[0][0],
163 LowestBandRate(sample_rate_hz_), 1);
164
peah4b572d02017-04-06 16:33:06 -0700165 // Compute and and apply the render delay required to achieve proper signal
166 // alignment.
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100167 estimated_delay_ = delay_controller_->GetDelay(
Per Åhgren5c532d32018-03-22 00:29:25 +0100168 render_buffer_->GetDownsampledRenderBuffer(), render_buffer_->Delay(),
169 echo_remover_delay_, (*capture_block)[0]);
peah4b572d02017-04-06 16:33:06 -0700170
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100171 if (estimated_delay_) {
172 if (render_buffer_->CausalDelay(estimated_delay_->delay)) {
173 bool delay_change = render_buffer_->SetDelay(estimated_delay_->delay);
174 if (delay_change) {
175 RTC_LOG(LS_WARNING) << "Delay changed to " << estimated_delay_->delay
176 << " at block " << capture_call_counter_;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100177 echo_path_variability.delay_change =
178 EchoPathVariability::DelayAdjustment::kNewDetectedDelay;
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100179 }
180 } else {
181 // A noncausal delay has been detected. This can only happen if there is
182 // clockdrift, an audio pipeline issue has occurred, an unreliable delay
183 // estimate is used or the specified minimum delay is too short.
184 if (estimated_delay_->quality == DelayEstimate::Quality::kRefined) {
Per Åhgrenc59a5762017-12-11 21:34:19 +0100185 echo_path_variability.delay_change =
186 EchoPathVariability::DelayAdjustment::kDelayReset;
Per Åhgren8b7d2062018-10-30 23:44:40 +0100187 delay_controller_->Reset(true);
Per Åhgrenc59a5762017-12-11 21:34:19 +0100188 render_buffer_->Reset();
189 capture_properly_started_ = false;
190 render_properly_started_ = false;
191 RTC_LOG(LS_WARNING) << "Reset due to noncausal delay at block "
192 << capture_call_counter_;
193 }
194 }
peah96b951c2017-08-22 10:26:07 -0700195 }
peah4b572d02017-04-06 16:33:06 -0700196
197 // Remove the echo from the capture signal.
198 echo_remover_->ProcessCapture(
Per Åhgren3ab308f2018-02-21 08:46:03 +0100199 echo_path_variability, capture_signal_saturation, estimated_delay_,
Per Åhgrende22a172017-12-20 18:00:51 +0100200 render_buffer_->GetRenderBuffer(), capture_block);
peah4b572d02017-04-06 16:33:06 -0700201
Per Åhgren5c532d32018-03-22 00:29:25 +0100202 // Check to see if a refined delay estimate has been obtained from the echo
203 // remover.
204 echo_remover_delay_ = echo_remover_->Delay();
205
peahcf02cf12017-04-05 14:18:07 -0700206 // Update the metrics.
Per Åhgren8ba58612017-12-01 23:01:44 +0100207 metrics_.UpdateCapture(false);
peahcf02cf12017-04-05 14:18:07 -0700208
Per Åhgren8ba58612017-12-01 23:01:44 +0100209 render_event_ = RenderDelayBuffer::BufferingEvent::kNone;
peahd0263542017-01-03 04:20:34 -0800210}
211
peahcf02cf12017-04-05 14:18:07 -0700212void BlockProcessorImpl::BufferRender(
213 const std::vector<std::vector<float>>& block) {
214 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), block.size());
215 RTC_DCHECK_EQ(kBlockSize, block[0].size());
216 data_dumper_->DumpRaw("aec3_processblock_call_order",
217 static_cast<int>(BlockProcessorApiCall::kRender));
218 data_dumper_->DumpWav("aec3_processblock_render_input", kBlockSize,
219 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
peahcf02cf12017-04-05 14:18:07 -0700220 data_dumper_->DumpWav("aec3_processblock_render_input2", kBlockSize,
221 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
222
Per Åhgren8ba58612017-12-01 23:01:44 +0100223 render_event_ = render_buffer_->Insert(block);
peahcf02cf12017-04-05 14:18:07 -0700224
Per Åhgren8ba58612017-12-01 23:01:44 +0100225 metrics_.UpdateRender(render_event_ !=
226 RenderDelayBuffer::BufferingEvent::kNone);
227
228 render_properly_started_ = true;
Per Åhgren47127762018-02-13 12:59:33 +0100229 delay_controller_->LogRenderCall();
peahd0263542017-01-03 04:20:34 -0800230}
231
peah69221db2017-01-27 03:28:19 -0800232void BlockProcessorImpl::UpdateEchoLeakageStatus(bool leakage_detected) {
233 echo_remover_->UpdateEchoLeakageStatus(leakage_detected);
234}
peahd0263542017-01-03 04:20:34 -0800235
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100236void BlockProcessorImpl::GetMetrics(EchoControl::Metrics* metrics) const {
237 echo_remover_->GetMetrics(metrics);
Per Åhgren83c4a022017-11-27 12:07:09 +0100238 const int block_size_ms = sample_rate_hz_ == 8000 ? 8 : 4;
Danil Chapovalovdb9f7ab2018-06-19 10:50:11 +0200239 absl::optional<size_t> delay = render_buffer_->Delay();
Per Åhgrenc59a5762017-12-11 21:34:19 +0100240 metrics->delay_ms = delay ? static_cast<int>(*delay) * block_size_ms : 0;
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100241}
242
Per Åhgrend0fa8202018-04-18 09:35:13 +0200243void BlockProcessorImpl::SetAudioBufferDelay(size_t delay_ms) {
244 render_buffer_->SetAudioBufferDelay(delay_ms);
245}
246
peahd0263542017-01-03 04:20:34 -0800247} // namespace
248
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200249BlockProcessor* BlockProcessor::Create(const EchoCanceller3Config& config,
250 int sample_rate_hz) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100251 std::unique_ptr<RenderDelayBuffer> render_buffer(
252 RenderDelayBuffer::Create(config, NumBandsForRate(sample_rate_hz)));
peah69221db2017-01-27 03:28:19 -0800253 std::unique_ptr<RenderDelayController> delay_controller(
Per Åhgrenc59a5762017-12-11 21:34:19 +0100254 RenderDelayController::Create(
255 config, RenderDelayBuffer::DelayEstimatorOffset(config),
256 sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800257 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700258 EchoRemover::Create(config, sample_rate_hz));
259 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800260 std::move(delay_controller), std::move(echo_remover));
261}
262
263BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200264 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800265 int sample_rate_hz,
266 std::unique_ptr<RenderDelayBuffer> render_buffer) {
267 std::unique_ptr<RenderDelayController> delay_controller(
Per Åhgrenc59a5762017-12-11 21:34:19 +0100268 RenderDelayController::Create(
269 config, RenderDelayBuffer::DelayEstimatorOffset(config),
270 sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800271 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700272 EchoRemover::Create(config, sample_rate_hz));
273 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800274 std::move(delay_controller), std::move(echo_remover));
275}
276
277BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200278 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800279 int sample_rate_hz,
280 std::unique_ptr<RenderDelayBuffer> render_buffer,
281 std::unique_ptr<RenderDelayController> delay_controller,
282 std::unique_ptr<EchoRemover> echo_remover) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100283 return new BlockProcessorImpl(
284 config, sample_rate_hz, std::move(render_buffer),
285 std::move(delay_controller), std::move(echo_remover));
peahd0263542017-01-03 04:20:34 -0800286}
287
288} // namespace webrtc