blob: 953b5f4c50cd0a010130498221a789c51166aa7e [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:
peah69221db2017-01-27 03:28:19 -080028 BlockProcessorImpl(int sample_rate_hz,
29 std::unique_ptr<RenderDelayBuffer> render_buffer,
30 std::unique_ptr<RenderDelayController> delay_controller,
31 std::unique_ptr<EchoRemover> echo_remover);
32
peahd0263542017-01-03 04:20:34 -080033 ~BlockProcessorImpl() override;
34
peah69221db2017-01-27 03:28:19 -080035 void ProcessCapture(bool echo_path_gain_change,
36 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080037 std::vector<std::vector<float>>* capture_block) override;
38
peahcf02cf12017-04-05 14:18:07 -070039 void BufferRender(const std::vector<std::vector<float>>& block) override;
peahd0263542017-01-03 04:20:34 -080040
peah69221db2017-01-27 03:28:19 -080041 void UpdateEchoLeakageStatus(bool leakage_detected) override;
peahd0263542017-01-03 04:20:34 -080042
43 private:
peahd0263542017-01-03 04:20:34 -080044 static int instance_count_;
peahcf02cf12017-04-05 14:18:07 -070045 bool no_capture_data_received_ = true;
46 bool no_render_data_received_ = true;
peahd0263542017-01-03 04:20:34 -080047 std::unique_ptr<ApmDataDumper> data_dumper_;
peah69221db2017-01-27 03:28:19 -080048 const size_t sample_rate_hz_;
49 std::unique_ptr<RenderDelayBuffer> render_buffer_;
50 std::unique_ptr<RenderDelayController> delay_controller_;
51 std::unique_ptr<EchoRemover> echo_remover_;
peahe985b3f2017-02-28 22:08:53 -080052 BlockProcessorMetrics metrics_;
peahcf02cf12017-04-05 14:18:07 -070053 bool render_buffer_overrun_occurred_ = false;
peahd0263542017-01-03 04:20:34 -080054 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BlockProcessorImpl);
55};
56
57int BlockProcessorImpl::instance_count_ = 0;
58
peah69221db2017-01-27 03:28:19 -080059BlockProcessorImpl::BlockProcessorImpl(
60 int sample_rate_hz,
61 std::unique_ptr<RenderDelayBuffer> render_buffer,
62 std::unique_ptr<RenderDelayController> delay_controller,
63 std::unique_ptr<EchoRemover> echo_remover)
64 : data_dumper_(
65 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
66 sample_rate_hz_(sample_rate_hz),
67 render_buffer_(std::move(render_buffer)),
68 delay_controller_(std::move(delay_controller)),
peah21920892017-02-08 05:08:56 -080069 echo_remover_(std::move(echo_remover)) {
70 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
71}
peahd0263542017-01-03 04:20:34 -080072
73BlockProcessorImpl::~BlockProcessorImpl() = default;
74
75void BlockProcessorImpl::ProcessCapture(
peah69221db2017-01-27 03:28:19 -080076 bool echo_path_gain_change,
77 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080078 std::vector<std::vector<float>>* capture_block) {
79 RTC_DCHECK(capture_block);
80 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), capture_block->size());
81 RTC_DCHECK_EQ(kBlockSize, (*capture_block)[0].size());
peahcf02cf12017-04-05 14:18:07 -070082 data_dumper_->DumpRaw("aec3_processblock_call_order",
83 static_cast<int>(BlockProcessorApiCall::kCapture));
84 data_dumper_->DumpWav("aec3_processblock_capture_input", kBlockSize,
85 &(*capture_block)[0][0],
86 LowestBandRate(sample_rate_hz_), 1);
peah69221db2017-01-27 03:28:19 -080087
peahcf02cf12017-04-05 14:18:07 -070088 // Do not start processing until render data has been buffered as that will
89 // cause the buffers to be wrongly aligned.
90 no_capture_data_received_ = false;
91 if (no_render_data_received_) {
92 return;
peah69221db2017-01-27 03:28:19 -080093 }
94
peahcf02cf12017-04-05 14:18:07 -070095 data_dumper_->DumpWav("aec3_processblock_capture_input2", kBlockSize,
96 &(*capture_block)[0][0],
97 LowestBandRate(sample_rate_hz_), 1);
98
99 bool render_buffer_underrun = false;
100 if (render_buffer_overrun_occurred_) {
101 // Reset the render buffers and the alignment functionality when there has
102 // been a render buffer overrun as the buffer alignment may be noncausal.
103 delay_controller_->Reset();
104 render_buffer_->Reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100105 RTC_LOG(LS_WARNING) << "Reset due to detected render buffer overrun.";
peah69221db2017-01-27 03:28:19 -0800106 }
peahcf02cf12017-04-05 14:18:07 -0700107
peah4b572d02017-04-06 16:33:06 -0700108 // Update the render buffers with new render data, filling the buffers with
109 // empty blocks when there is no render data available.
110 render_buffer_underrun = !render_buffer_->UpdateBuffers();
Per Åhgrenfe9f2222017-09-26 23:33:26 +0200111 if (render_buffer_underrun) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100112 RTC_LOG(LS_WARNING) << "Render API jitter buffer underrun.";
Per Åhgrenfe9f2222017-09-26 23:33:26 +0200113 }
peah4b572d02017-04-06 16:33:06 -0700114
115 // Compute and and apply the render delay required to achieve proper signal
116 // alignment.
117 const size_t old_delay = render_buffer_->Delay();
118 const size_t new_delay = delay_controller_->GetDelay(
119 render_buffer_->GetDownsampledRenderBuffer(), (*capture_block)[0]);
peah4b572d02017-04-06 16:33:06 -0700120
peah96b951c2017-08-22 10:26:07 -0700121 bool delay_change;
122 if (new_delay >= kMinEchoPathDelayBlocks) {
123 render_buffer_->SetDelay(new_delay);
124 const size_t achieved_delay = render_buffer_->Delay();
125 delay_change = old_delay != achieved_delay || old_delay != new_delay ||
126 render_buffer_overrun_occurred_;
127
128 // Inform the delay controller of the actually set delay to allow it to
129 // properly react to a non-feasible delay.
130 delay_controller_->SetDelay(achieved_delay);
131 } else {
132 delay_controller_->Reset();
133 render_buffer_->Reset();
134 delay_change = true;
Mirko Bonadei675513b2017-11-09 11:09:25 +0100135 RTC_LOG(LS_WARNING) << "Reset due to noncausal delay.";
peah96b951c2017-08-22 10:26:07 -0700136 }
peah4b572d02017-04-06 16:33:06 -0700137
138 // Remove the echo from the capture signal.
139 echo_remover_->ProcessCapture(
140 delay_controller_->AlignmentHeadroomSamples(),
peah96b951c2017-08-22 10:26:07 -0700141 EchoPathVariability(echo_path_gain_change, delay_change),
peah4b572d02017-04-06 16:33:06 -0700142 capture_signal_saturation, render_buffer_->GetRenderBuffer(),
143 capture_block);
144
peahcf02cf12017-04-05 14:18:07 -0700145 // Update the metrics.
146 metrics_.UpdateCapture(render_buffer_underrun);
147
148 render_buffer_overrun_occurred_ = false;
peahd0263542017-01-03 04:20:34 -0800149}
150
peahcf02cf12017-04-05 14:18:07 -0700151void BlockProcessorImpl::BufferRender(
152 const std::vector<std::vector<float>>& block) {
153 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), block.size());
154 RTC_DCHECK_EQ(kBlockSize, block[0].size());
155 data_dumper_->DumpRaw("aec3_processblock_call_order",
156 static_cast<int>(BlockProcessorApiCall::kRender));
157 data_dumper_->DumpWav("aec3_processblock_render_input", kBlockSize,
158 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
peah69221db2017-01-27 03:28:19 -0800159
peahcf02cf12017-04-05 14:18:07 -0700160 no_render_data_received_ = false;
161
162 // Do not start buffer render data until capture data has been received as
163 // that data may give a false alignment.
164 if (no_capture_data_received_) {
165 return;
peah69221db2017-01-27 03:28:19 -0800166 }
peahcf02cf12017-04-05 14:18:07 -0700167
168 data_dumper_->DumpWav("aec3_processblock_render_input2", kBlockSize,
169 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
170
171 // Buffer the render data.
172 render_buffer_overrun_occurred_ = !render_buffer_->Insert(block);
173
174 // Update the metrics.
175 metrics_.UpdateRender(render_buffer_overrun_occurred_);
peahd0263542017-01-03 04:20:34 -0800176}
177
peah69221db2017-01-27 03:28:19 -0800178void BlockProcessorImpl::UpdateEchoLeakageStatus(bool leakage_detected) {
179 echo_remover_->UpdateEchoLeakageStatus(leakage_detected);
180}
peahd0263542017-01-03 04:20:34 -0800181
182} // namespace
183
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200184BlockProcessor* BlockProcessor::Create(const EchoCanceller3Config& config,
185 int sample_rate_hz) {
peahcf02cf12017-04-05 14:18:07 -0700186 std::unique_ptr<RenderDelayBuffer> render_buffer(
187 RenderDelayBuffer::Create(NumBandsForRate(sample_rate_hz)));
peah69221db2017-01-27 03:28:19 -0800188 std::unique_ptr<RenderDelayController> delay_controller(
peah4fed3c02017-08-30 06:58:44 -0700189 RenderDelayController::Create(config, sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800190 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700191 EchoRemover::Create(config, sample_rate_hz));
192 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800193 std::move(delay_controller), std::move(echo_remover));
194}
195
196BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200197 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800198 int sample_rate_hz,
199 std::unique_ptr<RenderDelayBuffer> render_buffer) {
200 std::unique_ptr<RenderDelayController> delay_controller(
peah4fed3c02017-08-30 06:58:44 -0700201 RenderDelayController::Create(config, sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800202 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700203 EchoRemover::Create(config, sample_rate_hz));
204 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800205 std::move(delay_controller), std::move(echo_remover));
206}
207
208BlockProcessor* BlockProcessor::Create(
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200209 const EchoCanceller3Config& config,
peah69221db2017-01-27 03:28:19 -0800210 int sample_rate_hz,
211 std::unique_ptr<RenderDelayBuffer> render_buffer,
212 std::unique_ptr<RenderDelayController> delay_controller,
213 std::unique_ptr<EchoRemover> echo_remover) {
214 return new BlockProcessorImpl(sample_rate_hz, std::move(render_buffer),
215 std::move(delay_controller),
216 std::move(echo_remover));
peahd0263542017-01-03 04:20:34 -0800217}
218
219} // namespace webrtc