blob: 1bb69584cc3fbf7932c1a672217d1f5e0d569a78 [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
Danil Chapovalovdb9f7ab2018-06-19 10:50:11 +020012#include "absl/types/optional.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/audio_processing/aec3/aec3_common.h"
14#include "modules/audio_processing/aec3/block_processor_metrics.h"
15#include "modules/audio_processing/aec3/echo_path_variability.h"
16#include "modules/audio_processing/logging/apm_data_dumper.h"
17#include "rtc_base/atomicops.h"
18#include "rtc_base/constructormagic.h"
Per Åhgrenfe9f2222017-09-26 23:33:26 +020019#include "rtc_base/logging.h"
peahd0263542017-01-03 04:20:34 -080020
21namespace webrtc {
22namespace {
23
peahcf02cf12017-04-05 14:18:07 -070024enum class BlockProcessorApiCall { kCapture, kRender };
25
peahd0263542017-01-03 04:20:34 -080026class BlockProcessorImpl final : public BlockProcessor {
27 public:
Per Åhgren8ba58612017-12-01 23:01:44 +010028 BlockProcessorImpl(const EchoCanceller3Config& config,
29 int sample_rate_hz,
peah69221db2017-01-27 03:28:19 -080030 std::unique_ptr<RenderDelayBuffer> render_buffer,
31 std::unique_ptr<RenderDelayController> delay_controller,
32 std::unique_ptr<EchoRemover> echo_remover);
33
peahd0263542017-01-03 04:20:34 -080034 ~BlockProcessorImpl() override;
35
peah69221db2017-01-27 03:28:19 -080036 void ProcessCapture(bool echo_path_gain_change,
37 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080038 std::vector<std::vector<float>>* capture_block) override;
39
peahcf02cf12017-04-05 14:18:07 -070040 void BufferRender(const std::vector<std::vector<float>>& block) override;
peahd0263542017-01-03 04:20:34 -080041
peah69221db2017-01-27 03:28:19 -080042 void UpdateEchoLeakageStatus(bool leakage_detected) override;
peahd0263542017-01-03 04:20:34 -080043
Gustaf Ullberg332150d2017-11-22 14:17:39 +010044 void GetMetrics(EchoControl::Metrics* metrics) const override;
45
Per Åhgrend0fa8202018-04-18 09:35:13 +020046 void SetAudioBufferDelay(size_t delay_ms) override;
47
peahd0263542017-01-03 04:20:34 -080048 private:
peahd0263542017-01-03 04:20:34 -080049 static int instance_count_;
50 std::unique_ptr<ApmDataDumper> data_dumper_;
Per Åhgren8ba58612017-12-01 23:01:44 +010051 const EchoCanceller3Config config_;
52 bool capture_properly_started_ = false;
53 bool render_properly_started_ = false;
peah69221db2017-01-27 03:28:19 -080054 const size_t sample_rate_hz_;
55 std::unique_ptr<RenderDelayBuffer> render_buffer_;
56 std::unique_ptr<RenderDelayController> delay_controller_;
57 std::unique_ptr<EchoRemover> echo_remover_;
peahe985b3f2017-02-28 22:08:53 -080058 BlockProcessorMetrics metrics_;
Per Åhgren8ba58612017-12-01 23:01:44 +010059 RenderDelayBuffer::BufferingEvent render_event_;
Per Åhgrenc59a5762017-12-11 21:34:19 +010060 size_t capture_call_counter_ = 0;
Danil Chapovalovdb9f7ab2018-06-19 10:50:11 +020061 absl::optional<DelayEstimate> estimated_delay_;
62 absl::optional<int> echo_remover_delay_;
peahd0263542017-01-03 04:20:34 -080063 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BlockProcessorImpl);
64};
65
66int BlockProcessorImpl::instance_count_ = 0;
67
peah69221db2017-01-27 03:28:19 -080068BlockProcessorImpl::BlockProcessorImpl(
Per Åhgren8ba58612017-12-01 23:01:44 +010069 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -080070 int sample_rate_hz,
71 std::unique_ptr<RenderDelayBuffer> render_buffer,
72 std::unique_ptr<RenderDelayController> delay_controller,
73 std::unique_ptr<EchoRemover> echo_remover)
74 : data_dumper_(
75 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
Per Åhgren8ba58612017-12-01 23:01:44 +010076 config_(config),
peah69221db2017-01-27 03:28:19 -080077 sample_rate_hz_(sample_rate_hz),
78 render_buffer_(std::move(render_buffer)),
79 delay_controller_(std::move(delay_controller)),
Per Åhgren8ba58612017-12-01 23:01:44 +010080 echo_remover_(std::move(echo_remover)),
81 render_event_(RenderDelayBuffer::BufferingEvent::kNone) {
peah21920892017-02-08 05:08:56 -080082 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
83}
peahd0263542017-01-03 04:20:34 -080084
85BlockProcessorImpl::~BlockProcessorImpl() = default;
86
87void BlockProcessorImpl::ProcessCapture(
peah69221db2017-01-27 03:28:19 -080088 bool echo_path_gain_change,
89 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080090 std::vector<std::vector<float>>* capture_block) {
91 RTC_DCHECK(capture_block);
92 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), capture_block->size());
93 RTC_DCHECK_EQ(kBlockSize, (*capture_block)[0].size());
Per Åhgrenc59a5762017-12-11 21:34:19 +010094
95 capture_call_counter_++;
96
peahcf02cf12017-04-05 14:18:07 -070097 data_dumper_->DumpRaw("aec3_processblock_call_order",
98 static_cast<int>(BlockProcessorApiCall::kCapture));
99 data_dumper_->DumpWav("aec3_processblock_capture_input", kBlockSize,
100 &(*capture_block)[0][0],
101 LowestBandRate(sample_rate_hz_), 1);
peah69221db2017-01-27 03:28:19 -0800102
Per Åhgren8ba58612017-12-01 23:01:44 +0100103 if (render_properly_started_) {
104 if (!capture_properly_started_) {
105 capture_properly_started_ = true;
106 render_buffer_->Reset();
Per Åhgren47127762018-02-13 12:59:33 +0100107 delay_controller_->Reset();
Per Åhgren8ba58612017-12-01 23:01:44 +0100108 }
109 } else {
110 // If no render data has yet arrived, do not process the capture signal.
peahcf02cf12017-04-05 14:18:07 -0700111 return;
peah69221db2017-01-27 03:28:19 -0800112 }
113
Per Åhgren8ba58612017-12-01 23:01:44 +0100114 EchoPathVariability echo_path_variability(
115 echo_path_gain_change, EchoPathVariability::DelayAdjustment::kNone,
116 false);
117
118 if (render_event_ == RenderDelayBuffer::BufferingEvent::kRenderOverrun &&
119 render_properly_started_) {
120 echo_path_variability.delay_change =
121 EchoPathVariability::DelayAdjustment::kBufferFlush;
122 delay_controller_->Reset();
Per Åhgrenc59a5762017-12-11 21:34:19 +0100123 RTC_LOG(LS_WARNING) << "Reset due to render buffer overrun at block "
124 << capture_call_counter_;
Per Åhgren8ba58612017-12-01 23:01:44 +0100125 }
126
127 // Update the render buffers with any newly arrived render blocks and prepare
128 // the render buffers for reading the render data corresponding to the current
129 // capture block.
Per Åhgrenc59a5762017-12-11 21:34:19 +0100130 render_event_ = render_buffer_->PrepareCaptureProcessing();
Per Åhgren8ba58612017-12-01 23:01:44 +0100131 RTC_DCHECK(RenderDelayBuffer::BufferingEvent::kRenderOverrun !=
132 render_event_);
133 if (render_event_ == RenderDelayBuffer::BufferingEvent::kRenderUnderrun) {
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100134 if (estimated_delay_ &&
135 estimated_delay_->quality == DelayEstimate::Quality::kRefined) {
136 echo_path_variability.delay_change =
137 EchoPathVariability::DelayAdjustment::kDelayReset;
138 delay_controller_->Reset();
139 capture_properly_started_ = false;
140 render_properly_started_ = false;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100141
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100142 RTC_LOG(LS_WARNING) << "Reset due to render buffer underrrun at block "
143 << capture_call_counter_;
144 }
Per Åhgren8ba58612017-12-01 23:01:44 +0100145 } else if (render_event_ == RenderDelayBuffer::BufferingEvent::kApiCallSkew) {
146 // There have been too many render calls in a row. Reset to avoid noncausal
147 // echo.
148 echo_path_variability.delay_change =
149 EchoPathVariability::DelayAdjustment::kDelayReset;
150 delay_controller_->Reset();
Per Åhgren8ba58612017-12-01 23:01:44 +0100151 capture_properly_started_ = false;
152 render_properly_started_ = false;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100153 RTC_LOG(LS_WARNING) << "Reset due to render buffer api skew at block "
154 << capture_call_counter_;
Per Åhgren8ba58612017-12-01 23:01:44 +0100155 }
156
peahcf02cf12017-04-05 14:18:07 -0700157 data_dumper_->DumpWav("aec3_processblock_capture_input2", kBlockSize,
158 &(*capture_block)[0][0],
159 LowestBandRate(sample_rate_hz_), 1);
160
peah4b572d02017-04-06 16:33:06 -0700161 // Compute and and apply the render delay required to achieve proper signal
162 // alignment.
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100163 estimated_delay_ = delay_controller_->GetDelay(
Per Åhgren5c532d32018-03-22 00:29:25 +0100164 render_buffer_->GetDownsampledRenderBuffer(), render_buffer_->Delay(),
165 echo_remover_delay_, (*capture_block)[0]);
peah4b572d02017-04-06 16:33:06 -0700166
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100167 if (estimated_delay_) {
168 if (render_buffer_->CausalDelay(estimated_delay_->delay)) {
169 bool delay_change = render_buffer_->SetDelay(estimated_delay_->delay);
170 if (delay_change) {
171 RTC_LOG(LS_WARNING) << "Delay changed to " << estimated_delay_->delay
172 << " at block " << capture_call_counter_;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100173 echo_path_variability.delay_change =
174 EchoPathVariability::DelayAdjustment::kNewDetectedDelay;
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100175 }
176 } else {
177 // A noncausal delay has been detected. This can only happen if there is
178 // clockdrift, an audio pipeline issue has occurred, an unreliable delay
179 // estimate is used or the specified minimum delay is too short.
180 if (estimated_delay_->quality == DelayEstimate::Quality::kRefined) {
Per Åhgrenc59a5762017-12-11 21:34:19 +0100181 echo_path_variability.delay_change =
182 EchoPathVariability::DelayAdjustment::kDelayReset;
183 delay_controller_->Reset();
184 render_buffer_->Reset();
185 capture_properly_started_ = false;
186 render_properly_started_ = false;
187 RTC_LOG(LS_WARNING) << "Reset due to noncausal delay at block "
188 << capture_call_counter_;
189 }
190 }
peah96b951c2017-08-22 10:26:07 -0700191 }
peah4b572d02017-04-06 16:33:06 -0700192
193 // Remove the echo from the capture signal.
194 echo_remover_->ProcessCapture(
Per Åhgren3ab308f2018-02-21 08:46:03 +0100195 echo_path_variability, capture_signal_saturation, estimated_delay_,
Per Åhgrende22a172017-12-20 18:00:51 +0100196 render_buffer_->GetRenderBuffer(), capture_block);
peah4b572d02017-04-06 16:33:06 -0700197
Per Åhgren5c532d32018-03-22 00:29:25 +0100198 // Check to see if a refined delay estimate has been obtained from the echo
199 // remover.
200 echo_remover_delay_ = echo_remover_->Delay();
201
peahcf02cf12017-04-05 14:18:07 -0700202 // Update the metrics.
Per Åhgren8ba58612017-12-01 23:01:44 +0100203 metrics_.UpdateCapture(false);
peahcf02cf12017-04-05 14:18:07 -0700204
Per Åhgren8ba58612017-12-01 23:01:44 +0100205 render_event_ = RenderDelayBuffer::BufferingEvent::kNone;
peahd0263542017-01-03 04:20:34 -0800206}
207
peahcf02cf12017-04-05 14:18:07 -0700208void BlockProcessorImpl::BufferRender(
209 const std::vector<std::vector<float>>& block) {
210 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), block.size());
211 RTC_DCHECK_EQ(kBlockSize, block[0].size());
212 data_dumper_->DumpRaw("aec3_processblock_call_order",
213 static_cast<int>(BlockProcessorApiCall::kRender));
214 data_dumper_->DumpWav("aec3_processblock_render_input", kBlockSize,
215 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
peahcf02cf12017-04-05 14:18:07 -0700216 data_dumper_->DumpWav("aec3_processblock_render_input2", kBlockSize,
217 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
218
Per Åhgren8ba58612017-12-01 23:01:44 +0100219 render_event_ = render_buffer_->Insert(block);
peahcf02cf12017-04-05 14:18:07 -0700220
Per Åhgren8ba58612017-12-01 23:01:44 +0100221 metrics_.UpdateRender(render_event_ !=
222 RenderDelayBuffer::BufferingEvent::kNone);
223
224 render_properly_started_ = true;
Per Åhgren47127762018-02-13 12:59:33 +0100225 delay_controller_->LogRenderCall();
peahd0263542017-01-03 04:20:34 -0800226}
227
peah69221db2017-01-27 03:28:19 -0800228void BlockProcessorImpl::UpdateEchoLeakageStatus(bool leakage_detected) {
229 echo_remover_->UpdateEchoLeakageStatus(leakage_detected);
230}
peahd0263542017-01-03 04:20:34 -0800231
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100232void BlockProcessorImpl::GetMetrics(EchoControl::Metrics* metrics) const {
233 echo_remover_->GetMetrics(metrics);
Per Åhgren83c4a022017-11-27 12:07:09 +0100234 const int block_size_ms = sample_rate_hz_ == 8000 ? 8 : 4;
Danil Chapovalovdb9f7ab2018-06-19 10:50:11 +0200235 absl::optional<size_t> delay = render_buffer_->Delay();
Per Åhgrenc59a5762017-12-11 21:34:19 +0100236 metrics->delay_ms = delay ? static_cast<int>(*delay) * block_size_ms : 0;
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100237}
238
Per Åhgrend0fa8202018-04-18 09:35:13 +0200239void BlockProcessorImpl::SetAudioBufferDelay(size_t delay_ms) {
240 render_buffer_->SetAudioBufferDelay(delay_ms);
241}
242
peahd0263542017-01-03 04:20:34 -0800243} // namespace
244
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200245BlockProcessor* BlockProcessor::Create(const EchoCanceller3Config& config,
246 int sample_rate_hz) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100247 std::unique_ptr<RenderDelayBuffer> render_buffer(
248 RenderDelayBuffer::Create(config, NumBandsForRate(sample_rate_hz)));
peah69221db2017-01-27 03:28:19 -0800249 std::unique_ptr<RenderDelayController> delay_controller(
Per Åhgrenc59a5762017-12-11 21:34:19 +0100250 RenderDelayController::Create(
251 config, RenderDelayBuffer::DelayEstimatorOffset(config),
252 sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800253 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700254 EchoRemover::Create(config, sample_rate_hz));
255 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800256 std::move(delay_controller), std::move(echo_remover));
257}
258
259BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200260 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800261 int sample_rate_hz,
262 std::unique_ptr<RenderDelayBuffer> render_buffer) {
263 std::unique_ptr<RenderDelayController> delay_controller(
Per Åhgrenc59a5762017-12-11 21:34:19 +0100264 RenderDelayController::Create(
265 config, RenderDelayBuffer::DelayEstimatorOffset(config),
266 sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800267 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700268 EchoRemover::Create(config, sample_rate_hz));
269 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800270 std::move(delay_controller), std::move(echo_remover));
271}
272
273BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200274 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800275 int sample_rate_hz,
276 std::unique_ptr<RenderDelayBuffer> render_buffer,
277 std::unique_ptr<RenderDelayController> delay_controller,
278 std::unique_ptr<EchoRemover> echo_remover) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100279 return new BlockProcessorImpl(
280 config, sample_rate_hz, std::move(render_buffer),
281 std::move(delay_controller), std::move(echo_remover));
peahd0263542017-01-03 04:20:34 -0800282}
283
284} // namespace webrtc