blob: ff11bae8e1dd9bbc1ec55c7688b993a2d7abe1da [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_;
Per Åhgren5c532d32018-03-22 00:29:25 +010060 rtc::Optional<int> echo_remover_delay_;
peahd0263542017-01-03 04:20:34 -080061 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BlockProcessorImpl);
62};
63
64int BlockProcessorImpl::instance_count_ = 0;
65
peah69221db2017-01-27 03:28:19 -080066BlockProcessorImpl::BlockProcessorImpl(
Per Åhgren8ba58612017-12-01 23:01:44 +010067 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -080068 int sample_rate_hz,
69 std::unique_ptr<RenderDelayBuffer> render_buffer,
70 std::unique_ptr<RenderDelayController> delay_controller,
71 std::unique_ptr<EchoRemover> echo_remover)
72 : data_dumper_(
73 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
Per Åhgren8ba58612017-12-01 23:01:44 +010074 config_(config),
peah69221db2017-01-27 03:28:19 -080075 sample_rate_hz_(sample_rate_hz),
76 render_buffer_(std::move(render_buffer)),
77 delay_controller_(std::move(delay_controller)),
Per Åhgren8ba58612017-12-01 23:01:44 +010078 echo_remover_(std::move(echo_remover)),
79 render_event_(RenderDelayBuffer::BufferingEvent::kNone) {
peah21920892017-02-08 05:08:56 -080080 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
81}
peahd0263542017-01-03 04:20:34 -080082
83BlockProcessorImpl::~BlockProcessorImpl() = default;
84
85void BlockProcessorImpl::ProcessCapture(
peah69221db2017-01-27 03:28:19 -080086 bool echo_path_gain_change,
87 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080088 std::vector<std::vector<float>>* capture_block) {
89 RTC_DCHECK(capture_block);
90 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), capture_block->size());
91 RTC_DCHECK_EQ(kBlockSize, (*capture_block)[0].size());
Per Åhgrenc59a5762017-12-11 21:34:19 +010092
93 capture_call_counter_++;
94
peahcf02cf12017-04-05 14:18:07 -070095 data_dumper_->DumpRaw("aec3_processblock_call_order",
96 static_cast<int>(BlockProcessorApiCall::kCapture));
97 data_dumper_->DumpWav("aec3_processblock_capture_input", kBlockSize,
98 &(*capture_block)[0][0],
99 LowestBandRate(sample_rate_hz_), 1);
peah69221db2017-01-27 03:28:19 -0800100
Per Åhgren8ba58612017-12-01 23:01:44 +0100101 if (render_properly_started_) {
102 if (!capture_properly_started_) {
103 capture_properly_started_ = true;
104 render_buffer_->Reset();
Per Åhgren47127762018-02-13 12:59:33 +0100105 delay_controller_->Reset();
Per Åhgren8ba58612017-12-01 23:01:44 +0100106 }
107 } else {
108 // If no render data has yet arrived, do not process the capture signal.
peahcf02cf12017-04-05 14:18:07 -0700109 return;
peah69221db2017-01-27 03:28:19 -0800110 }
111
Per Åhgren8ba58612017-12-01 23:01:44 +0100112 EchoPathVariability echo_path_variability(
113 echo_path_gain_change, EchoPathVariability::DelayAdjustment::kNone,
114 false);
115
116 if (render_event_ == RenderDelayBuffer::BufferingEvent::kRenderOverrun &&
117 render_properly_started_) {
118 echo_path_variability.delay_change =
119 EchoPathVariability::DelayAdjustment::kBufferFlush;
120 delay_controller_->Reset();
Per Åhgrenc59a5762017-12-11 21:34:19 +0100121 RTC_LOG(LS_WARNING) << "Reset due to render buffer overrun at block "
122 << capture_call_counter_;
Per Åhgren8ba58612017-12-01 23:01:44 +0100123 }
124
125 // Update the render buffers with any newly arrived render blocks and prepare
126 // the render buffers for reading the render data corresponding to the current
127 // capture block.
Per Åhgrenc59a5762017-12-11 21:34:19 +0100128 render_event_ = render_buffer_->PrepareCaptureProcessing();
Per Åhgren8ba58612017-12-01 23:01:44 +0100129 RTC_DCHECK(RenderDelayBuffer::BufferingEvent::kRenderOverrun !=
130 render_event_);
131 if (render_event_ == RenderDelayBuffer::BufferingEvent::kRenderUnderrun) {
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100132 if (estimated_delay_ &&
133 estimated_delay_->quality == DelayEstimate::Quality::kRefined) {
134 echo_path_variability.delay_change =
135 EchoPathVariability::DelayAdjustment::kDelayReset;
136 delay_controller_->Reset();
137 capture_properly_started_ = false;
138 render_properly_started_ = false;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100139
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100140 RTC_LOG(LS_WARNING) << "Reset due to render buffer underrrun at block "
141 << capture_call_counter_;
142 }
Per Åhgren8ba58612017-12-01 23:01:44 +0100143 } else if (render_event_ == RenderDelayBuffer::BufferingEvent::kApiCallSkew) {
144 // There have been too many render calls in a row. Reset to avoid noncausal
145 // echo.
146 echo_path_variability.delay_change =
147 EchoPathVariability::DelayAdjustment::kDelayReset;
148 delay_controller_->Reset();
Per Åhgren8ba58612017-12-01 23:01:44 +0100149 capture_properly_started_ = false;
150 render_properly_started_ = false;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100151 RTC_LOG(LS_WARNING) << "Reset due to render buffer api skew at block "
152 << capture_call_counter_;
Per Åhgren8ba58612017-12-01 23:01:44 +0100153 }
154
peahcf02cf12017-04-05 14:18:07 -0700155 data_dumper_->DumpWav("aec3_processblock_capture_input2", kBlockSize,
156 &(*capture_block)[0][0],
157 LowestBandRate(sample_rate_hz_), 1);
158
peah4b572d02017-04-06 16:33:06 -0700159 // Compute and and apply the render delay required to achieve proper signal
160 // alignment.
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100161 estimated_delay_ = delay_controller_->GetDelay(
Per Åhgren5c532d32018-03-22 00:29:25 +0100162 render_buffer_->GetDownsampledRenderBuffer(), render_buffer_->Delay(),
163 echo_remover_delay_, (*capture_block)[0]);
peah4b572d02017-04-06 16:33:06 -0700164
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100165 if (estimated_delay_) {
166 if (render_buffer_->CausalDelay(estimated_delay_->delay)) {
167 bool delay_change = render_buffer_->SetDelay(estimated_delay_->delay);
168 if (delay_change) {
169 RTC_LOG(LS_WARNING) << "Delay changed to " << estimated_delay_->delay
170 << " at block " << capture_call_counter_;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100171 echo_path_variability.delay_change =
172 EchoPathVariability::DelayAdjustment::kNewDetectedDelay;
Per Åhgrena76ef9d2018-01-25 07:01:34 +0100173 }
174 } else {
175 // A noncausal delay has been detected. This can only happen if there is
176 // clockdrift, an audio pipeline issue has occurred, an unreliable delay
177 // estimate is used or the specified minimum delay is too short.
178 if (estimated_delay_->quality == DelayEstimate::Quality::kRefined) {
Per Åhgrenc59a5762017-12-11 21:34:19 +0100179 echo_path_variability.delay_change =
180 EchoPathVariability::DelayAdjustment::kDelayReset;
181 delay_controller_->Reset();
182 render_buffer_->Reset();
183 capture_properly_started_ = false;
184 render_properly_started_ = false;
185 RTC_LOG(LS_WARNING) << "Reset due to noncausal delay at block "
186 << capture_call_counter_;
187 }
188 }
peah96b951c2017-08-22 10:26:07 -0700189 }
peah4b572d02017-04-06 16:33:06 -0700190
191 // Remove the echo from the capture signal.
192 echo_remover_->ProcessCapture(
Per Åhgren3ab308f2018-02-21 08:46:03 +0100193 echo_path_variability, capture_signal_saturation, estimated_delay_,
Per Åhgrende22a172017-12-20 18:00:51 +0100194 render_buffer_->GetRenderBuffer(), capture_block);
peah4b572d02017-04-06 16:33:06 -0700195
Per Åhgren5c532d32018-03-22 00:29:25 +0100196 // Check to see if a refined delay estimate has been obtained from the echo
197 // remover.
198 echo_remover_delay_ = echo_remover_->Delay();
199
peahcf02cf12017-04-05 14:18:07 -0700200 // Update the metrics.
Per Åhgren8ba58612017-12-01 23:01:44 +0100201 metrics_.UpdateCapture(false);
peahcf02cf12017-04-05 14:18:07 -0700202
Per Åhgren8ba58612017-12-01 23:01:44 +0100203 render_event_ = RenderDelayBuffer::BufferingEvent::kNone;
peahd0263542017-01-03 04:20:34 -0800204}
205
peahcf02cf12017-04-05 14:18:07 -0700206void BlockProcessorImpl::BufferRender(
207 const std::vector<std::vector<float>>& block) {
208 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), block.size());
209 RTC_DCHECK_EQ(kBlockSize, block[0].size());
210 data_dumper_->DumpRaw("aec3_processblock_call_order",
211 static_cast<int>(BlockProcessorApiCall::kRender));
212 data_dumper_->DumpWav("aec3_processblock_render_input", kBlockSize,
213 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
peahcf02cf12017-04-05 14:18:07 -0700214 data_dumper_->DumpWav("aec3_processblock_render_input2", kBlockSize,
215 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
216
Per Åhgren8ba58612017-12-01 23:01:44 +0100217 render_event_ = render_buffer_->Insert(block);
peahcf02cf12017-04-05 14:18:07 -0700218
Per Åhgren8ba58612017-12-01 23:01:44 +0100219 metrics_.UpdateRender(render_event_ !=
220 RenderDelayBuffer::BufferingEvent::kNone);
221
222 render_properly_started_ = true;
Per Åhgren47127762018-02-13 12:59:33 +0100223 delay_controller_->LogRenderCall();
peahd0263542017-01-03 04:20:34 -0800224}
225
peah69221db2017-01-27 03:28:19 -0800226void BlockProcessorImpl::UpdateEchoLeakageStatus(bool leakage_detected) {
227 echo_remover_->UpdateEchoLeakageStatus(leakage_detected);
228}
peahd0263542017-01-03 04:20:34 -0800229
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100230void BlockProcessorImpl::GetMetrics(EchoControl::Metrics* metrics) const {
231 echo_remover_->GetMetrics(metrics);
Per Åhgren83c4a022017-11-27 12:07:09 +0100232 const int block_size_ms = sample_rate_hz_ == 8000 ? 8 : 4;
Per Åhgrenc59a5762017-12-11 21:34:19 +0100233 rtc::Optional<size_t> delay = render_buffer_->Delay();
234 metrics->delay_ms = delay ? static_cast<int>(*delay) * block_size_ms : 0;
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100235}
236
peahd0263542017-01-03 04:20:34 -0800237} // namespace
238
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200239BlockProcessor* BlockProcessor::Create(const EchoCanceller3Config& config,
240 int sample_rate_hz) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100241 std::unique_ptr<RenderDelayBuffer> render_buffer(
242 RenderDelayBuffer::Create(config, NumBandsForRate(sample_rate_hz)));
peah69221db2017-01-27 03:28:19 -0800243 std::unique_ptr<RenderDelayController> delay_controller(
Per Åhgrenc59a5762017-12-11 21:34:19 +0100244 RenderDelayController::Create(
245 config, RenderDelayBuffer::DelayEstimatorOffset(config),
246 sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800247 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700248 EchoRemover::Create(config, sample_rate_hz));
249 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800250 std::move(delay_controller), std::move(echo_remover));
251}
252
253BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200254 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800255 int sample_rate_hz,
256 std::unique_ptr<RenderDelayBuffer> render_buffer) {
257 std::unique_ptr<RenderDelayController> delay_controller(
Per Åhgrenc59a5762017-12-11 21:34:19 +0100258 RenderDelayController::Create(
259 config, RenderDelayBuffer::DelayEstimatorOffset(config),
260 sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800261 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700262 EchoRemover::Create(config, sample_rate_hz));
263 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800264 std::move(delay_controller), std::move(echo_remover));
265}
266
267BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200268 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800269 int sample_rate_hz,
270 std::unique_ptr<RenderDelayBuffer> render_buffer,
271 std::unique_ptr<RenderDelayController> delay_controller,
272 std::unique_ptr<EchoRemover> echo_remover) {
Per Åhgren8ba58612017-12-01 23:01:44 +0100273 return new BlockProcessorImpl(
274 config, sample_rate_hz, std::move(render_buffer),
275 std::move(delay_controller), std::move(echo_remover));
peahd0263542017-01-03 04:20:34 -0800276}
277
278} // namespace webrtc