1 /*
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
11 #include "modules/audio_processing/aec3/block_processor.h"
12
13 #include <memory>
14 #include <string>
15 #include <vector>
16
17 #include "modules/audio_processing/aec3/aec3_common.h"
18 #include "modules/audio_processing/aec3/mock/mock_echo_remover.h"
19 #include "modules/audio_processing/aec3/mock/mock_render_delay_buffer.h"
20 #include "modules/audio_processing/aec3/mock/mock_render_delay_controller.h"
21 #include "modules/audio_processing/test/echo_canceller_test_tools.h"
22 #include "rtc_base/checks.h"
23 #include "rtc_base/random.h"
24 #include "rtc_base/strings/string_builder.h"
25 #include "test/gmock.h"
26 #include "test/gtest.h"
27
28 namespace webrtc {
29 namespace {
30
31 using ::testing::_;
32 using ::testing::AtLeast;
33 using ::testing::NiceMock;
34 using ::testing::Return;
35 using ::testing::StrictMock;
36
37 // Verifies that the basic BlockProcessor functionality works and that the API
38 // methods are callable.
RunBasicSetupAndApiCallTest(int sample_rate_hz,int num_iterations)39 void RunBasicSetupAndApiCallTest(int sample_rate_hz, int num_iterations) {
40 constexpr size_t kNumRenderChannels = 1;
41 constexpr size_t kNumCaptureChannels = 1;
42
43 std::unique_ptr<BlockProcessor> block_processor(
44 BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
45 kNumRenderChannels, kNumCaptureChannels));
46 Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels, 1000.f);
47 for (int k = 0; k < num_iterations; ++k) {
48 block_processor->BufferRender(block);
49 block_processor->ProcessCapture(false, false, nullptr, &block);
50 block_processor->UpdateEchoLeakageStatus(false);
51 }
52 }
53
54 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
RunRenderBlockSizeVerificationTest(int sample_rate_hz)55 void RunRenderBlockSizeVerificationTest(int sample_rate_hz) {
56 constexpr size_t kNumRenderChannels = 1;
57 constexpr size_t kNumCaptureChannels = 1;
58
59 std::unique_ptr<BlockProcessor> block_processor(
60 BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
61 kNumRenderChannels, kNumCaptureChannels));
62 Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels);
63
64 EXPECT_DEATH(block_processor->BufferRender(block), "");
65 }
66
RunRenderNumBandsVerificationTest(int sample_rate_hz)67 void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
68 constexpr size_t kNumRenderChannels = 1;
69 constexpr size_t kNumCaptureChannels = 1;
70
71 const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
72 ? NumBandsForRate(sample_rate_hz) + 1
73 : 1;
74 std::unique_ptr<BlockProcessor> block_processor(
75 BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
76 kNumRenderChannels, kNumCaptureChannels));
77 Block block(wrong_num_bands, kNumRenderChannels);
78
79 EXPECT_DEATH(block_processor->BufferRender(block), "");
80 }
81
RunCaptureNumBandsVerificationTest(int sample_rate_hz)82 void RunCaptureNumBandsVerificationTest(int sample_rate_hz) {
83 constexpr size_t kNumRenderChannels = 1;
84 constexpr size_t kNumCaptureChannels = 1;
85
86 const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
87 ? NumBandsForRate(sample_rate_hz) + 1
88 : 1;
89 std::unique_ptr<BlockProcessor> block_processor(
90 BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
91 kNumRenderChannels, kNumCaptureChannels));
92 Block block(wrong_num_bands, kNumRenderChannels);
93
94 EXPECT_DEATH(block_processor->ProcessCapture(false, false, nullptr, &block),
95 "");
96 }
97 #endif
98
ProduceDebugText(int sample_rate_hz)99 std::string ProduceDebugText(int sample_rate_hz) {
100 rtc::StringBuilder ss;
101 ss << "Sample rate: " << sample_rate_hz;
102 return ss.Release();
103 }
104
FillSampleVector(int call_counter,int delay,rtc::ArrayView<float> samples)105 void FillSampleVector(int call_counter,
106 int delay,
107 rtc::ArrayView<float> samples) {
108 for (size_t i = 0; i < samples.size(); ++i) {
109 samples[i] = (call_counter - delay) * 10000.0f + i;
110 }
111 }
112
113 } // namespace
114
115 // Verifies that the delay controller functionality is properly integrated with
116 // the render delay buffer inside block processor.
117 // TODO(peah): Activate the unittest once the required code has been landed.
TEST(BlockProcessor,DISABLED_DelayControllerIntegration)118 TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
119 constexpr size_t kNumRenderChannels = 1;
120 constexpr size_t kNumCaptureChannels = 1;
121 constexpr size_t kNumBlocks = 310;
122 constexpr size_t kDelayInSamples = 640;
123 constexpr size_t kDelayHeadroom = 1;
124 constexpr size_t kDelayInBlocks =
125 kDelayInSamples / kBlockSize - kDelayHeadroom;
126 Random random_generator(42U);
127 for (auto rate : {16000, 32000, 48000}) {
128 SCOPED_TRACE(ProduceDebugText(rate));
129 std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
130 render_delay_buffer_mock(
131 new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate, 1));
132 EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
133 .Times(kNumBlocks)
134 .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
135 EXPECT_CALL(*render_delay_buffer_mock, AlignFromDelay(kDelayInBlocks))
136 .Times(AtLeast(1));
137 EXPECT_CALL(*render_delay_buffer_mock, MaxDelay()).WillOnce(Return(30));
138 EXPECT_CALL(*render_delay_buffer_mock, Delay())
139 .Times(kNumBlocks + 1)
140 .WillRepeatedly(Return(0));
141 std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
142 EchoCanceller3Config(), rate, kNumRenderChannels, kNumCaptureChannels,
143 std::move(render_delay_buffer_mock)));
144
145 Block render_block(NumBandsForRate(rate), kNumRenderChannels);
146 Block capture_block(NumBandsForRate(rate), kNumCaptureChannels);
147 DelayBuffer<float> signal_delay_buffer(kDelayInSamples);
148 for (size_t k = 0; k < kNumBlocks; ++k) {
149 RandomizeSampleVector(&random_generator,
150 render_block.View(/*band=*/0, /*capture=*/0));
151 signal_delay_buffer.Delay(render_block.View(/*band=*/0, /*capture=*/0),
152 capture_block.View(/*band=*/0, /*capture=*/0));
153 block_processor->BufferRender(render_block);
154 block_processor->ProcessCapture(false, false, nullptr, &capture_block);
155 }
156 }
157 }
158
159 // Verifies that BlockProcessor submodules are called in a proper manner.
TEST(BlockProcessor,DISABLED_SubmoduleIntegration)160 TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
161 constexpr size_t kNumBlocks = 310;
162 constexpr size_t kNumRenderChannels = 1;
163 constexpr size_t kNumCaptureChannels = 1;
164
165 Random random_generator(42U);
166 for (auto rate : {16000, 32000, 48000}) {
167 SCOPED_TRACE(ProduceDebugText(rate));
168 std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
169 render_delay_buffer_mock(
170 new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate, 1));
171 std::unique_ptr<
172 ::testing::StrictMock<webrtc::test::MockRenderDelayController>>
173 render_delay_controller_mock(
174 new StrictMock<webrtc::test::MockRenderDelayController>());
175 std::unique_ptr<testing::StrictMock<webrtc::test::MockEchoRemover>>
176 echo_remover_mock(new StrictMock<webrtc::test::MockEchoRemover>());
177
178 EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
179 .Times(kNumBlocks - 1)
180 .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
181 EXPECT_CALL(*render_delay_buffer_mock, PrepareCaptureProcessing())
182 .Times(kNumBlocks);
183 EXPECT_CALL(*render_delay_buffer_mock, AlignFromDelay(9)).Times(AtLeast(1));
184 EXPECT_CALL(*render_delay_buffer_mock, Delay())
185 .Times(kNumBlocks)
186 .WillRepeatedly(Return(0));
187 EXPECT_CALL(*render_delay_controller_mock, GetDelay(_, _, _))
188 .Times(kNumBlocks);
189 EXPECT_CALL(*echo_remover_mock, ProcessCapture(_, _, _, _, _, _))
190 .Times(kNumBlocks);
191 EXPECT_CALL(*echo_remover_mock, UpdateEchoLeakageStatus(_))
192 .Times(kNumBlocks);
193
194 std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
195 EchoCanceller3Config(), rate, kNumRenderChannels, kNumCaptureChannels,
196 std::move(render_delay_buffer_mock),
197 std::move(render_delay_controller_mock), std::move(echo_remover_mock)));
198
199 Block render_block(NumBandsForRate(rate), kNumRenderChannels);
200 Block capture_block(NumBandsForRate(rate), kNumCaptureChannels);
201 DelayBuffer<float> signal_delay_buffer(640);
202 for (size_t k = 0; k < kNumBlocks; ++k) {
203 RandomizeSampleVector(&random_generator,
204 render_block.View(/*band=*/0, /*capture=*/0));
205 signal_delay_buffer.Delay(render_block.View(/*band=*/0, /*capture=*/0),
206 capture_block.View(/*band=*/0, /*capture=*/0));
207 block_processor->BufferRender(render_block);
208 block_processor->ProcessCapture(false, false, nullptr, &capture_block);
209 block_processor->UpdateEchoLeakageStatus(false);
210 }
211 }
212 }
213
TEST(BlockProcessor,BasicSetupAndApiCalls)214 TEST(BlockProcessor, BasicSetupAndApiCalls) {
215 for (auto rate : {16000, 32000, 48000}) {
216 SCOPED_TRACE(ProduceDebugText(rate));
217 RunBasicSetupAndApiCallTest(rate, 1);
218 }
219 }
220
TEST(BlockProcessor,TestLongerCall)221 TEST(BlockProcessor, TestLongerCall) {
222 RunBasicSetupAndApiCallTest(16000, 20 * kNumBlocksPerSecond);
223 }
224
225 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
226 // TODO(gustaf): Re-enable the test once the issue with memory leaks during
227 // DEATH tests on test bots has been fixed.
TEST(BlockProcessorDeathTest,DISABLED_VerifyRenderBlockSizeCheck)228 TEST(BlockProcessorDeathTest, DISABLED_VerifyRenderBlockSizeCheck) {
229 for (auto rate : {16000, 32000, 48000}) {
230 SCOPED_TRACE(ProduceDebugText(rate));
231 RunRenderBlockSizeVerificationTest(rate);
232 }
233 }
234
TEST(BlockProcessorDeathTest,VerifyRenderNumBandsCheck)235 TEST(BlockProcessorDeathTest, VerifyRenderNumBandsCheck) {
236 for (auto rate : {16000, 32000, 48000}) {
237 SCOPED_TRACE(ProduceDebugText(rate));
238 RunRenderNumBandsVerificationTest(rate);
239 }
240 }
241
242 // TODO(peah): Verify the check for correct number of bands in the capture
243 // signal.
TEST(BlockProcessorDeathTest,VerifyCaptureNumBandsCheck)244 TEST(BlockProcessorDeathTest, VerifyCaptureNumBandsCheck) {
245 for (auto rate : {16000, 32000, 48000}) {
246 SCOPED_TRACE(ProduceDebugText(rate));
247 RunCaptureNumBandsVerificationTest(rate);
248 }
249 }
250
251 // Verifiers that the verification for null ProcessCapture input works.
TEST(BlockProcessorDeathTest,NullProcessCaptureParameter)252 TEST(BlockProcessorDeathTest, NullProcessCaptureParameter) {
253 EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
254 BlockProcessor::Create(EchoCanceller3Config(), 16000, 1, 1))
255 ->ProcessCapture(false, false, nullptr, nullptr),
256 "");
257 }
258
259 // Verifies the check for correct sample rate.
260 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
261 // tests on test bots has been fixed.
TEST(BlockProcessor,DISABLED_WrongSampleRate)262 TEST(BlockProcessor, DISABLED_WrongSampleRate) {
263 EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
264 BlockProcessor::Create(EchoCanceller3Config(), 8001, 1, 1)),
265 "");
266 }
267
268 #endif
269
270 // Verifies that external delay estimator delays are applied correctly when a
271 // call begins with a sequence of capture blocks.
TEST(BlockProcessor,ExternalDelayAppliedCorrectlyWithInitialCaptureCalls)272 TEST(BlockProcessor, ExternalDelayAppliedCorrectlyWithInitialCaptureCalls) {
273 constexpr int kNumRenderChannels = 1;
274 constexpr int kNumCaptureChannels = 1;
275 constexpr int kSampleRateHz = 16000;
276
277 EchoCanceller3Config config;
278 config.delay.use_external_delay_estimator = true;
279
280 std::unique_ptr<RenderDelayBuffer> delay_buffer(
281 RenderDelayBuffer::Create(config, kSampleRateHz, kNumRenderChannels));
282
283 std::unique_ptr<testing::NiceMock<webrtc::test::MockEchoRemover>>
284 echo_remover_mock(new NiceMock<webrtc::test::MockEchoRemover>());
285 webrtc::test::MockEchoRemover* echo_remover_mock_pointer =
286 echo_remover_mock.get();
287
288 std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
289 config, kSampleRateHz, kNumRenderChannels, kNumCaptureChannels,
290 std::move(delay_buffer), /*delay_controller=*/nullptr,
291 std::move(echo_remover_mock)));
292
293 Block render_block(NumBandsForRate(kSampleRateHz), kNumRenderChannels);
294 Block capture_block(NumBandsForRate(kSampleRateHz), kNumCaptureChannels);
295
296 // Process...
297 // - 10 capture calls, where no render data is available,
298 // - 10 render calls, populating the buffer,
299 // - 2 capture calls, verifying that the delay was applied correctly.
300 constexpr int kDelayInBlocks = 5;
301 constexpr int kDelayInMs = 20;
302 block_processor->SetAudioBufferDelay(kDelayInMs);
303
304 int capture_call_counter = 0;
305 int render_call_counter = 0;
306 for (size_t k = 0; k < 10; ++k) {
307 FillSampleVector(++capture_call_counter, kDelayInBlocks,
308 capture_block.View(/*band=*/0, /*capture=*/0));
309 block_processor->ProcessCapture(false, false, nullptr, &capture_block);
310 }
311 for (size_t k = 0; k < 10; ++k) {
312 FillSampleVector(++render_call_counter, 0,
313 render_block.View(/*band=*/0, /*capture=*/0));
314 block_processor->BufferRender(render_block);
315 }
316
317 EXPECT_CALL(*echo_remover_mock_pointer, ProcessCapture)
318 .WillRepeatedly(
319 [](EchoPathVariability /*echo_path_variability*/,
320 bool /*capture_signal_saturation*/,
321 const absl::optional<DelayEstimate>& /*external_delay*/,
322 RenderBuffer* render_buffer, Block* /*linear_output*/,
323 Block* capture) {
324 const auto& render = render_buffer->GetBlock(0);
325 const auto render_view = render.View(/*band=*/0, /*channel=*/0);
326 const auto capture_view = capture->View(/*band=*/0, /*channel=*/0);
327 for (size_t i = 0; i < kBlockSize; ++i) {
328 EXPECT_FLOAT_EQ(render_view[i], capture_view[i]);
329 }
330 });
331
332 FillSampleVector(++capture_call_counter, kDelayInBlocks,
333 capture_block.View(/*band=*/0, /*capture=*/0));
334 block_processor->ProcessCapture(false, false, nullptr, &capture_block);
335
336 FillSampleVector(++capture_call_counter, kDelayInBlocks,
337 capture_block.View(/*band=*/0, /*capture=*/0));
338 block_processor->ProcessCapture(false, false, nullptr, &capture_block);
339 }
340
341 } // namespace webrtc
342