blob: 7f702ff0a50e3782cda1ef2b584389bda0bdbaab [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020012#include "api/optional.h"
13#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
peahd0263542017-01-03 04:20:34 -080046 private:
peahd0263542017-01-03 04:20:34 -080047 static int instance_count_;
48 std::unique_ptr<ApmDataDumper> data_dumper_;
Per Åhgren8ba58612017-12-01 23:01:44 +010049 const EchoCanceller3Config config_;
50 bool capture_properly_started_ = false;
51 bool render_properly_started_ = false;
peah69221db2017-01-27 03:28:19 -080052 const size_t sample_rate_hz_;
53 std::unique_ptr<RenderDelayBuffer> render_buffer_;
54 std::unique_ptr<RenderDelayController> delay_controller_;
55 std::unique_ptr<EchoRemover> echo_remover_;
peahe985b3f2017-02-28 22:08:53 -080056 BlockProcessorMetrics metrics_;
Per Åhgren8ba58612017-12-01 23:01:44 +010057 RenderDelayBuffer::BufferingEvent render_event_;
Per Åhgrenc59a5762017-12-11 21:34:19 +010058 size_t capture_call_counter_ = 0;
Per Åhgrena76ef9d2018-01-25 07:01:34 +010059 rtc::Optional<DelayEstimate> estimated_delay_;
peahd0263542017-01-03 04:20:34 -080060 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BlockProcessorImpl);
61};
62
63int BlockProcessorImpl::instance_count_ = 0;
64
peah69221db2017-01-27 03:28:19 -080065BlockProcessorImpl::BlockProcessorImpl(
Per Åhgren8ba58612017-12-01 23:01:44 +010066 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -080067 int sample_rate_hz,
68 std::unique_ptr<RenderDelayBuffer> render_buffer,
69 std::unique_ptr<RenderDelayController> delay_controller,
70 std::unique_ptr<EchoRemover> echo_remover)
71 : data_dumper_(
72 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
Per Åhgren8ba58612017-12-01 23:01:44 +010073 config_(config),
peah69221db2017-01-27 03:28:19 -080074 sample_rate_hz_(sample_rate_hz),
75 render_buffer_(std::move(render_buffer)),
76 delay_controller_(std::move(delay_controller)),
Per Åhgren8ba58612017-12-01 23:01:44 +010077 echo_remover_(std::move(echo_remover)),
78 render_event_(RenderDelayBuffer::BufferingEvent::kNone) {
peah21920892017-02-08 05:08:56 -080079 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
80}
peahd0263542017-01-03 04:20:34 -080081
82BlockProcessorImpl::~BlockProcessorImpl() = default;
83
84void BlockProcessorImpl::ProcessCapture(
peah69221db2017-01-27 03:28:19 -080085 bool echo_path_gain_change,
86 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080087 std::vector<std::vector<float>>* capture_block) {
88 RTC_DCHECK(capture_block);
89 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), capture_block->size());
90 RTC_DCHECK_EQ(kBlockSize, (*capture_block)[0].size());
Per Åhgrenc59a5762017-12-11 21:34:19 +010091
92 capture_call_counter_++;
93
peahcf02cf12017-04-05 14:18:07 -070094 data_dumper_->DumpRaw("aec3_processblock_call_order",
95 static_cast<int>(BlockProcessorApiCall::kCapture));
96 data_dumper_->DumpWav("aec3_processblock_capture_input", kBlockSize,
97 &(*capture_block)[0][0],
98 LowestBandRate(sample_rate_hz_), 1);
peah69221db2017-01-27 03:28:19 -080099
Per Åhgren8ba58612017-12-01 23:01:44 +0100100 if (render_properly_started_) {
101 if (!capture_properly_started_) {
102 capture_properly_started_ = true;
103 render_buffer_->Reset();
Per Åhgren47127762018-02-13 12:59:33 +0100104 delay_controller_->Reset();
Per Åhgren8ba58612017-12-01 23:01:44 +0100105 }
106 } else {
107 // If no render data has yet arrived, do not process the capture signal.
peahcf02cf12017-04-05 14:18:07 -0700108 return;
peah69221db2017-01-27 03:28:19 -0800109 }
110
Per Åhgren8ba58612017-12-01 23:01:44 +0100111 EchoPathVariability echo_path_variability(
112 echo_path_gain_change, EchoPathVariability::DelayAdjustment::kNone,
113 false);
114
115 if (render_event_ == RenderDelayBuffer::BufferingEvent::kRenderOverrun &&
116 render_properly_started_) {
117 echo_path_variability.delay_change =
118 EchoPathVariability::DelayAdjustment::kBufferFlush;
119 delay_controller_->Reset();
Per Åhgrenc59a5762017-12-11 21:34:19 +0100120 RTC_LOG(LS_WARNING) << "Reset due to render buffer overrun at block "
121 << capture_call_counter_;
Per Åhgren8ba58612017-12-01 23:01:44 +0100122 }
123
124 // Update the render buffers with any newly arrived render blocks and prepare
125 // the render buffers for reading the render data corresponding to the current
126 // capture block.
Per Åhgrenc59a5762017-12-11 21:34:19 +0100127 render_event_ = render_buffer_->PrepareCaptureProcessing();
Per Åhgren8ba58612017-12-01 23:01:44 +0100128 RTC_DCHECK(RenderDelayBuffer::BufferingEvent::kRenderOverrun !=
129 render_event_);
130 if (render_event_ == RenderDelayBuffer::BufferingEvent::kRenderUnderrun) {
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100131 if (estimated_delay_ &&
132 estimated_delay_->quality == DelayEstimate::Quality::kRefined) {
133 echo_path_variability.delay_change =
134 EchoPathVariability::DelayAdjustment::kDelayReset;
135 delay_controller_->Reset();
136 capture_properly_started_ = false;
137 render_properly_started_ = false;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100138
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100139 RTC_LOG(LS_WARNING) << "Reset due to render buffer underrrun at block "
140 << capture_call_counter_;
141 }
Per Åhgren8ba58612017-12-01 23:01:44 +0100142 } else if (render_event_ == RenderDelayBuffer::BufferingEvent::kApiCallSkew) {
143 // There have been too many render calls in a row. Reset to avoid noncausal
144 // echo.
145 echo_path_variability.delay_change =
146 EchoPathVariability::DelayAdjustment::kDelayReset;
147 delay_controller_->Reset();
Per Åhgren8ba58612017-12-01 23:01:44 +0100148 capture_properly_started_ = false;
149 render_properly_started_ = false;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100150 RTC_LOG(LS_WARNING) << "Reset due to render buffer api skew at block "
151 << capture_call_counter_;
Per Åhgren8ba58612017-12-01 23:01:44 +0100152 }
153
peahcf02cf12017-04-05 14:18:07 -0700154 data_dumper_->DumpWav("aec3_processblock_capture_input2", kBlockSize,
155 &(*capture_block)[0][0],
156 LowestBandRate(sample_rate_hz_), 1);
157
peah4b572d02017-04-06 16:33:06 -0700158 // Compute and and apply the render delay required to achieve proper signal
159 // alignment.
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100160 estimated_delay_ = delay_controller_->GetDelay(
peah4b572d02017-04-06 16:33:06 -0700161 render_buffer_->GetDownsampledRenderBuffer(), (*capture_block)[0]);
peah4b572d02017-04-06 16:33:06 -0700162
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100163 if (estimated_delay_) {
164 if (render_buffer_->CausalDelay(estimated_delay_->delay)) {
165 bool delay_change = render_buffer_->SetDelay(estimated_delay_->delay);
166 if (delay_change) {
167 RTC_LOG(LS_WARNING) << "Delay changed to " << estimated_delay_->delay
168 << " at block " << capture_call_counter_;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100169 echo_path_variability.delay_change =
170 EchoPathVariability::DelayAdjustment::kNewDetectedDelay;
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100171 }
172 } else {
173 // A noncausal delay has been detected. This can only happen if there is
174 // clockdrift, an audio pipeline issue has occurred, an unreliable delay
175 // estimate is used or the specified minimum delay is too short.
176 if (estimated_delay_->quality == DelayEstimate::Quality::kRefined) {
Per Åhgrenc59a5762017-12-11 21:34:19 +0100177 echo_path_variability.delay_change =
178 EchoPathVariability::DelayAdjustment::kDelayReset;
179 delay_controller_->Reset();
180 render_buffer_->Reset();
181 capture_properly_started_ = false;
182 render_properly_started_ = false;
183 RTC_LOG(LS_WARNING) << "Reset due to noncausal delay at block "
184 << capture_call_counter_;
185 }
186 }
peah96b951c2017-08-22 10:26:07 -0700187 }
peah4b572d02017-04-06 16:33:06 -0700188
189 // Remove the echo from the capture signal.
190 echo_remover_->ProcessCapture(
Per Åhgren3ab308f2018-02-21 08:46:03 +0100191 echo_path_variability, capture_signal_saturation, estimated_delay_,
Per Åhgrende22a172017-12-20 18:00:51 +0100192 render_buffer_->GetRenderBuffer(), capture_block);
peah4b572d02017-04-06 16:33:06 -0700193
peahcf02cf12017-04-05 14:18:07 -0700194 // Update the metrics.
Per Åhgren8ba58612017-12-01 23:01:44 +0100195 metrics_.UpdateCapture(false);
peahcf02cf12017-04-05 14:18:07 -0700196
Per Åhgren8ba58612017-12-01 23:01:44 +0100197 render_event_ = RenderDelayBuffer::BufferingEvent::kNone;
peahd0263542017-01-03 04:20:34 -0800198}
199
peahcf02cf12017-04-05 14:18:07 -0700200void BlockProcessorImpl::BufferRender(
201 const std::vector<std::vector<float>>& block) {
202 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), block.size());
203 RTC_DCHECK_EQ(kBlockSize, block[0].size());
204 data_dumper_->DumpRaw("aec3_processblock_call_order",
205 static_cast<int>(BlockProcessorApiCall::kRender));
206 data_dumper_->DumpWav("aec3_processblock_render_input", kBlockSize,
207 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
peahcf02cf12017-04-05 14:18:07 -0700208 data_dumper_->DumpWav("aec3_processblock_render_input2", kBlockSize,
209 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
210
Per Åhgren8ba58612017-12-01 23:01:44 +0100211 render_event_ = render_buffer_->Insert(block);
peahcf02cf12017-04-05 14:18:07 -0700212
Per Åhgren8ba58612017-12-01 23:01:44 +0100213 metrics_.UpdateRender(render_event_ !=
214 RenderDelayBuffer::BufferingEvent::kNone);
215
216 render_properly_started_ = true;
Per Åhgren47127762018-02-13 12:59:33 +0100217 delay_controller_->LogRenderCall();
peahd0263542017-01-03 04:20:34 -0800218}
219
peah69221db2017-01-27 03:28:19 -0800220void BlockProcessorImpl::UpdateEchoLeakageStatus(bool leakage_detected) {
221 echo_remover_->UpdateEchoLeakageStatus(leakage_detected);
222}
peahd0263542017-01-03 04:20:34 -0800223
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100224void BlockProcessorImpl::GetMetrics(EchoControl::Metrics* metrics) const {
225 echo_remover_->GetMetrics(metrics);
Per Åhgren83c4a022017-11-27 12:07:09 +0100226 const int block_size_ms = sample_rate_hz_ == 8000 ? 8 : 4;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100227 rtc::Optional<size_t> delay = render_buffer_->Delay();
228 metrics->delay_ms = delay ? static_cast<int>(*delay) * block_size_ms : 0;
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100229}
230
peahd0263542017-01-03 04:20:34 -0800231} // namespace
232
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200233BlockProcessor* BlockProcessor::Create(const EchoCanceller3Config& config,
234 int sample_rate_hz) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100235 std::unique_ptr<RenderDelayBuffer> render_buffer(
236 RenderDelayBuffer::Create(config, NumBandsForRate(sample_rate_hz)));
peah69221db2017-01-27 03:28:19 -0800237 std::unique_ptr<RenderDelayController> delay_controller(
Per Åhgrenc59a5762017-12-11 21:34:19 +0100238 RenderDelayController::Create(
239 config, RenderDelayBuffer::DelayEstimatorOffset(config),
240 sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800241 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700242 EchoRemover::Create(config, sample_rate_hz));
243 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800244 std::move(delay_controller), std::move(echo_remover));
245}
246
247BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200248 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800249 int sample_rate_hz,
250 std::unique_ptr<RenderDelayBuffer> render_buffer) {
251 std::unique_ptr<RenderDelayController> delay_controller(
Per Åhgrenc59a5762017-12-11 21:34:19 +0100252 RenderDelayController::Create(
253 config, RenderDelayBuffer::DelayEstimatorOffset(config),
254 sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800255 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700256 EchoRemover::Create(config, sample_rate_hz));
257 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800258 std::move(delay_controller), std::move(echo_remover));
259}
260
261BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200262 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800263 int sample_rate_hz,
264 std::unique_ptr<RenderDelayBuffer> render_buffer,
265 std::unique_ptr<RenderDelayController> delay_controller,
266 std::unique_ptr<EchoRemover> echo_remover) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100267 return new BlockProcessorImpl(
268 config, sample_rate_hz, std::move(render_buffer),
269 std::move(delay_controller), std::move(echo_remover));
peahd0263542017-01-03 04:20:34 -0800270}
271
272} // namespace webrtc