blob: 7bb9e15129af389f38fa2e6de3c5205191583801 [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 */
10#include "webrtc/modules/audio_processing/aec3/block_processor.h"
11
kwiberg84f6a3f2017-09-05 08:43:13 -070012#include "webrtc/api/optional.h"
peah522d71b2017-02-23 05:16:26 -080013#include "webrtc/modules/audio_processing/aec3/aec3_common.h"
peahe985b3f2017-02-28 22:08:53 -080014#include "webrtc/modules/audio_processing/aec3/block_processor_metrics.h"
peah69221db2017-01-27 03:28:19 -080015#include "webrtc/modules/audio_processing/aec3/echo_path_variability.h"
16#include "webrtc/modules/audio_processing/logging/apm_data_dumper.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020017#include "webrtc/rtc_base/atomicops.h"
18#include "webrtc/rtc_base/constructormagic.h"
peahd0263542017-01-03 04:20:34 -080019
20namespace webrtc {
21namespace {
22
peahcf02cf12017-04-05 14:18:07 -070023enum class BlockProcessorApiCall { kCapture, kRender };
24
peahd0263542017-01-03 04:20:34 -080025class BlockProcessorImpl final : public BlockProcessor {
26 public:
peah69221db2017-01-27 03:28:19 -080027 BlockProcessorImpl(int sample_rate_hz,
28 std::unique_ptr<RenderDelayBuffer> render_buffer,
29 std::unique_ptr<RenderDelayController> delay_controller,
30 std::unique_ptr<EchoRemover> echo_remover);
31
peahd0263542017-01-03 04:20:34 -080032 ~BlockProcessorImpl() override;
33
peah69221db2017-01-27 03:28:19 -080034 void ProcessCapture(bool echo_path_gain_change,
35 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080036 std::vector<std::vector<float>>* capture_block) override;
37
peahcf02cf12017-04-05 14:18:07 -070038 void BufferRender(const std::vector<std::vector<float>>& block) override;
peahd0263542017-01-03 04:20:34 -080039
peah69221db2017-01-27 03:28:19 -080040 void UpdateEchoLeakageStatus(bool leakage_detected) override;
peahd0263542017-01-03 04:20:34 -080041
42 private:
peahd0263542017-01-03 04:20:34 -080043 static int instance_count_;
peahcf02cf12017-04-05 14:18:07 -070044 bool no_capture_data_received_ = true;
45 bool no_render_data_received_ = true;
peahd0263542017-01-03 04:20:34 -080046 std::unique_ptr<ApmDataDumper> data_dumper_;
peah69221db2017-01-27 03:28:19 -080047 const size_t sample_rate_hz_;
48 std::unique_ptr<RenderDelayBuffer> render_buffer_;
49 std::unique_ptr<RenderDelayController> delay_controller_;
50 std::unique_ptr<EchoRemover> echo_remover_;
peahe985b3f2017-02-28 22:08:53 -080051 BlockProcessorMetrics metrics_;
peahcf02cf12017-04-05 14:18:07 -070052 bool render_buffer_overrun_occurred_ = false;
peahd0263542017-01-03 04:20:34 -080053 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BlockProcessorImpl);
54};
55
56int BlockProcessorImpl::instance_count_ = 0;
57
peah69221db2017-01-27 03:28:19 -080058BlockProcessorImpl::BlockProcessorImpl(
59 int sample_rate_hz,
60 std::unique_ptr<RenderDelayBuffer> render_buffer,
61 std::unique_ptr<RenderDelayController> delay_controller,
62 std::unique_ptr<EchoRemover> echo_remover)
63 : data_dumper_(
64 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
65 sample_rate_hz_(sample_rate_hz),
66 render_buffer_(std::move(render_buffer)),
67 delay_controller_(std::move(delay_controller)),
peah21920892017-02-08 05:08:56 -080068 echo_remover_(std::move(echo_remover)) {
69 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
70}
peahd0263542017-01-03 04:20:34 -080071
72BlockProcessorImpl::~BlockProcessorImpl() = default;
73
74void BlockProcessorImpl::ProcessCapture(
peah69221db2017-01-27 03:28:19 -080075 bool echo_path_gain_change,
76 bool capture_signal_saturation,
peahd0263542017-01-03 04:20:34 -080077 std::vector<std::vector<float>>* capture_block) {
78 RTC_DCHECK(capture_block);
79 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), capture_block->size());
80 RTC_DCHECK_EQ(kBlockSize, (*capture_block)[0].size());
peahcf02cf12017-04-05 14:18:07 -070081 data_dumper_->DumpRaw("aec3_processblock_call_order",
82 static_cast<int>(BlockProcessorApiCall::kCapture));
83 data_dumper_->DumpWav("aec3_processblock_capture_input", kBlockSize,
84 &(*capture_block)[0][0],
85 LowestBandRate(sample_rate_hz_), 1);
peah69221db2017-01-27 03:28:19 -080086
peahcf02cf12017-04-05 14:18:07 -070087 // Do not start processing until render data has been buffered as that will
88 // cause the buffers to be wrongly aligned.
89 no_capture_data_received_ = false;
90 if (no_render_data_received_) {
91 return;
peah69221db2017-01-27 03:28:19 -080092 }
93
peahcf02cf12017-04-05 14:18:07 -070094 data_dumper_->DumpWav("aec3_processblock_capture_input2", kBlockSize,
95 &(*capture_block)[0][0],
96 LowestBandRate(sample_rate_hz_), 1);
97
98 bool render_buffer_underrun = false;
99 if (render_buffer_overrun_occurred_) {
100 // Reset the render buffers and the alignment functionality when there has
101 // been a render buffer overrun as the buffer alignment may be noncausal.
102 delay_controller_->Reset();
103 render_buffer_->Reset();
peah69221db2017-01-27 03:28:19 -0800104 }
peahcf02cf12017-04-05 14:18:07 -0700105
peah4b572d02017-04-06 16:33:06 -0700106 // Update the render buffers with new render data, filling the buffers with
107 // empty blocks when there is no render data available.
108 render_buffer_underrun = !render_buffer_->UpdateBuffers();
109
110 // Compute and and apply the render delay required to achieve proper signal
111 // alignment.
112 const size_t old_delay = render_buffer_->Delay();
113 const size_t new_delay = delay_controller_->GetDelay(
114 render_buffer_->GetDownsampledRenderBuffer(), (*capture_block)[0]);
peah4b572d02017-04-06 16:33:06 -0700115
peah96b951c2017-08-22 10:26:07 -0700116 bool delay_change;
117 if (new_delay >= kMinEchoPathDelayBlocks) {
118 render_buffer_->SetDelay(new_delay);
119 const size_t achieved_delay = render_buffer_->Delay();
120 delay_change = old_delay != achieved_delay || old_delay != new_delay ||
121 render_buffer_overrun_occurred_;
122
123 // Inform the delay controller of the actually set delay to allow it to
124 // properly react to a non-feasible delay.
125 delay_controller_->SetDelay(achieved_delay);
126 } else {
127 delay_controller_->Reset();
128 render_buffer_->Reset();
129 delay_change = true;
130 }
peah4b572d02017-04-06 16:33:06 -0700131
132 // Remove the echo from the capture signal.
133 echo_remover_->ProcessCapture(
134 delay_controller_->AlignmentHeadroomSamples(),
peah96b951c2017-08-22 10:26:07 -0700135 EchoPathVariability(echo_path_gain_change, delay_change),
peah4b572d02017-04-06 16:33:06 -0700136 capture_signal_saturation, render_buffer_->GetRenderBuffer(),
137 capture_block);
138
peahcf02cf12017-04-05 14:18:07 -0700139 // Update the metrics.
140 metrics_.UpdateCapture(render_buffer_underrun);
141
142 render_buffer_overrun_occurred_ = false;
peahd0263542017-01-03 04:20:34 -0800143}
144
peahcf02cf12017-04-05 14:18:07 -0700145void BlockProcessorImpl::BufferRender(
146 const std::vector<std::vector<float>>& block) {
147 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), block.size());
148 RTC_DCHECK_EQ(kBlockSize, block[0].size());
149 data_dumper_->DumpRaw("aec3_processblock_call_order",
150 static_cast<int>(BlockProcessorApiCall::kRender));
151 data_dumper_->DumpWav("aec3_processblock_render_input", kBlockSize,
152 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
peah69221db2017-01-27 03:28:19 -0800153
peahcf02cf12017-04-05 14:18:07 -0700154 no_render_data_received_ = false;
155
156 // Do not start buffer render data until capture data has been received as
157 // that data may give a false alignment.
158 if (no_capture_data_received_) {
159 return;
peah69221db2017-01-27 03:28:19 -0800160 }
peahcf02cf12017-04-05 14:18:07 -0700161
162 data_dumper_->DumpWav("aec3_processblock_render_input2", kBlockSize,
163 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
164
165 // Buffer the render data.
166 render_buffer_overrun_occurred_ = !render_buffer_->Insert(block);
167
168 // Update the metrics.
169 metrics_.UpdateRender(render_buffer_overrun_occurred_);
peahd0263542017-01-03 04:20:34 -0800170}
171
peah69221db2017-01-27 03:28:19 -0800172void BlockProcessorImpl::UpdateEchoLeakageStatus(bool leakage_detected) {
173 echo_remover_->UpdateEchoLeakageStatus(leakage_detected);
174}
peahd0263542017-01-03 04:20:34 -0800175
176} // namespace
177
peah697a5902017-06-30 07:06:10 -0700178BlockProcessor* BlockProcessor::Create(
179 const AudioProcessing::Config::EchoCanceller3& config,
180 int sample_rate_hz) {
peahcf02cf12017-04-05 14:18:07 -0700181 std::unique_ptr<RenderDelayBuffer> render_buffer(
182 RenderDelayBuffer::Create(NumBandsForRate(sample_rate_hz)));
peah69221db2017-01-27 03:28:19 -0800183 std::unique_ptr<RenderDelayController> delay_controller(
peah4fed3c02017-08-30 06:58:44 -0700184 RenderDelayController::Create(config, sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800185 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700186 EchoRemover::Create(config, sample_rate_hz));
187 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800188 std::move(delay_controller), std::move(echo_remover));
189}
190
191BlockProcessor* BlockProcessor::Create(
peah697a5902017-06-30 07:06:10 -0700192 const AudioProcessing::Config::EchoCanceller3& config,
peah69221db2017-01-27 03:28:19 -0800193 int sample_rate_hz,
194 std::unique_ptr<RenderDelayBuffer> render_buffer) {
195 std::unique_ptr<RenderDelayController> delay_controller(
peah4fed3c02017-08-30 06:58:44 -0700196 RenderDelayController::Create(config, sample_rate_hz));
peah69221db2017-01-27 03:28:19 -0800197 std::unique_ptr<EchoRemover> echo_remover(
peah697a5902017-06-30 07:06:10 -0700198 EchoRemover::Create(config, sample_rate_hz));
199 return Create(config, sample_rate_hz, std::move(render_buffer),
peah69221db2017-01-27 03:28:19 -0800200 std::move(delay_controller), std::move(echo_remover));
201}
202
203BlockProcessor* BlockProcessor::Create(
peah697a5902017-06-30 07:06:10 -0700204 const AudioProcessing::Config::EchoCanceller3& config,
peah69221db2017-01-27 03:28:19 -0800205 int sample_rate_hz,
206 std::unique_ptr<RenderDelayBuffer> render_buffer,
207 std::unique_ptr<RenderDelayController> delay_controller,
208 std::unique_ptr<EchoRemover> echo_remover) {
209 return new BlockProcessorImpl(sample_rate_hz, std::move(render_buffer),
210 std::move(delay_controller),
211 std::move(echo_remover));
peahd0263542017-01-03 04:20:34 -0800212}
213
214} // namespace webrtc