1 /*
2 * Copyright (c) 2017 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/render_delay_controller.h"
12
13 #include <algorithm>
14 #include <memory>
15 #include <string>
16 #include <vector>
17
18 #include "modules/audio_processing/aec3/aec3_common.h"
19 #include "modules/audio_processing/aec3/block_processor.h"
20 #include "modules/audio_processing/aec3/decimator.h"
21 #include "modules/audio_processing/aec3/render_delay_buffer.h"
22 #include "modules/audio_processing/logging/apm_data_dumper.h"
23 #include "modules/audio_processing/test/echo_canceller_test_tools.h"
24 #include "rtc_base/random.h"
25 #include "rtc_base/strings/string_builder.h"
26 #include "test/gtest.h"
27
28 namespace webrtc {
29 namespace {
30
ProduceDebugText(int sample_rate_hz)31 std::string ProduceDebugText(int sample_rate_hz) {
32 rtc::StringBuilder ss;
33 ss << "Sample rate: " << sample_rate_hz;
34 return ss.Release();
35 }
36
ProduceDebugText(int sample_rate_hz,size_t delay,size_t num_render_channels,size_t num_capture_channels)37 std::string ProduceDebugText(int sample_rate_hz,
38 size_t delay,
39 size_t num_render_channels,
40 size_t num_capture_channels) {
41 rtc::StringBuilder ss;
42 ss << ProduceDebugText(sample_rate_hz) << ", Delay: " << delay
43 << ", Num render channels: " << num_render_channels
44 << ", Num capture channels: " << num_capture_channels;
45 return ss.Release();
46 }
47
48 constexpr size_t kDownSamplingFactors[] = {2, 4, 8};
49
50 } // namespace
51
52 // Verifies the output of GetDelay when there are no AnalyzeRender calls.
53 // TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController,DISABLED_NoRenderSignal)54 TEST(RenderDelayController, DISABLED_NoRenderSignal) {
55 for (size_t num_render_channels : {1, 2, 8}) {
56 std::vector<std::vector<float>> block(1,
57 std::vector<float>(kBlockSize, 0.f));
58 EchoCanceller3Config config;
59 for (size_t num_matched_filters = 4; num_matched_filters <= 10;
60 num_matched_filters++) {
61 for (auto down_sampling_factor : kDownSamplingFactors) {
62 config.delay.down_sampling_factor = down_sampling_factor;
63 config.delay.num_filters = num_matched_filters;
64 for (auto rate : {16000, 32000, 48000}) {
65 SCOPED_TRACE(ProduceDebugText(rate));
66 std::unique_ptr<RenderDelayBuffer> delay_buffer(
67 RenderDelayBuffer::Create(config, rate, num_render_channels));
68 std::unique_ptr<RenderDelayController> delay_controller(
69 RenderDelayController::Create(config, rate,
70 /*num_capture_channels*/ 1));
71 for (size_t k = 0; k < 100; ++k) {
72 auto delay = delay_controller->GetDelay(
73 delay_buffer->GetDownsampledRenderBuffer(),
74 delay_buffer->Delay(), block);
75 EXPECT_FALSE(delay->delay);
76 }
77 }
78 }
79 }
80 }
81 }
82
83 // Verifies the basic API call sequence.
84 // TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController,DISABLED_BasicApiCalls)85 TEST(RenderDelayController, DISABLED_BasicApiCalls) {
86 for (size_t num_capture_channels : {1, 2, 4}) {
87 for (size_t num_render_channels : {1, 2, 8}) {
88 std::vector<std::vector<float>> capture_block(
89 num_capture_channels, std::vector<float>(kBlockSize, 0.f));
90 absl::optional<DelayEstimate> delay_blocks;
91 for (size_t num_matched_filters = 4; num_matched_filters <= 10;
92 num_matched_filters++) {
93 for (auto down_sampling_factor : kDownSamplingFactors) {
94 EchoCanceller3Config config;
95 config.delay.down_sampling_factor = down_sampling_factor;
96 config.delay.num_filters = num_matched_filters;
97 config.delay.capture_alignment_mixing.downmix = false;
98 config.delay.capture_alignment_mixing.adaptive_selection = false;
99
100 for (auto rate : {16000, 32000, 48000}) {
101 std::vector<std::vector<std::vector<float>>> render_block(
102 NumBandsForRate(rate),
103 std::vector<std::vector<float>>(
104 num_render_channels, std::vector<float>(kBlockSize, 0.f)));
105 std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
106 RenderDelayBuffer::Create(config, rate, num_render_channels));
107 std::unique_ptr<RenderDelayController> delay_controller(
108 RenderDelayController::Create(EchoCanceller3Config(), rate,
109 num_capture_channels));
110 for (size_t k = 0; k < 10; ++k) {
111 render_delay_buffer->Insert(render_block);
112 render_delay_buffer->PrepareCaptureProcessing();
113
114 delay_blocks = delay_controller->GetDelay(
115 render_delay_buffer->GetDownsampledRenderBuffer(),
116 render_delay_buffer->Delay(), capture_block);
117 }
118 EXPECT_TRUE(delay_blocks);
119 EXPECT_FALSE(delay_blocks->delay);
120 }
121 }
122 }
123 }
124 }
125 }
126
127 // Verifies that the RenderDelayController is able to align the signals for
128 // simple timeshifts between the signals.
129 // TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController,DISABLED_Alignment)130 TEST(RenderDelayController, DISABLED_Alignment) {
131 Random random_generator(42U);
132 for (size_t num_capture_channels : {1, 2, 4}) {
133 std::vector<std::vector<float>> capture_block(
134 num_capture_channels, std::vector<float>(kBlockSize, 0.f));
135 for (size_t num_matched_filters = 4; num_matched_filters <= 10;
136 num_matched_filters++) {
137 for (auto down_sampling_factor : kDownSamplingFactors) {
138 EchoCanceller3Config config;
139 config.delay.down_sampling_factor = down_sampling_factor;
140 config.delay.num_filters = num_matched_filters;
141 config.delay.capture_alignment_mixing.downmix = false;
142 config.delay.capture_alignment_mixing.adaptive_selection = false;
143
144 for (size_t num_render_channels : {1, 2, 8}) {
145 for (auto rate : {16000, 32000, 48000}) {
146 std::vector<std::vector<std::vector<float>>> render_block(
147 NumBandsForRate(rate),
148 std::vector<std::vector<float>>(
149 num_render_channels, std::vector<float>(kBlockSize, 0.f)));
150
151 for (size_t delay_samples : {15, 50, 150, 200, 800, 4000}) {
152 absl::optional<DelayEstimate> delay_blocks;
153 SCOPED_TRACE(ProduceDebugText(rate, delay_samples,
154 num_render_channels,
155 num_capture_channels));
156 std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
157 RenderDelayBuffer::Create(config, rate, num_render_channels));
158 std::unique_ptr<RenderDelayController> delay_controller(
159 RenderDelayController::Create(config, rate,
160 num_capture_channels));
161 DelayBuffer<float> signal_delay_buffer(delay_samples);
162 for (size_t k = 0; k < (400 + delay_samples / kBlockSize); ++k) {
163 for (size_t band = 0; band < render_block.size(); ++band) {
164 for (size_t channel = 0; channel < render_block[band].size();
165 ++channel) {
166 RandomizeSampleVector(&random_generator,
167 render_block[band][channel]);
168 }
169 }
170 signal_delay_buffer.Delay(render_block[0][0], capture_block[0]);
171 render_delay_buffer->Insert(render_block);
172 render_delay_buffer->PrepareCaptureProcessing();
173 delay_blocks = delay_controller->GetDelay(
174 render_delay_buffer->GetDownsampledRenderBuffer(),
175 render_delay_buffer->Delay(), capture_block);
176 }
177 ASSERT_TRUE(!!delay_blocks);
178
179 constexpr int kDelayHeadroomBlocks = 1;
180 size_t expected_delay_blocks =
181 std::max(0, static_cast<int>(delay_samples / kBlockSize) -
182 kDelayHeadroomBlocks);
183
184 EXPECT_EQ(expected_delay_blocks, delay_blocks->delay);
185 }
186 }
187 }
188 }
189 }
190 }
191 }
192
193 // Verifies that the RenderDelayController is able to properly handle noncausal
194 // delays.
195 // TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController,DISABLED_NonCausalAlignment)196 TEST(RenderDelayController, DISABLED_NonCausalAlignment) {
197 Random random_generator(42U);
198 for (size_t num_capture_channels : {1, 2, 4}) {
199 for (size_t num_render_channels : {1, 2, 8}) {
200 for (size_t num_matched_filters = 4; num_matched_filters <= 10;
201 num_matched_filters++) {
202 for (auto down_sampling_factor : kDownSamplingFactors) {
203 EchoCanceller3Config config;
204 config.delay.down_sampling_factor = down_sampling_factor;
205 config.delay.num_filters = num_matched_filters;
206 config.delay.capture_alignment_mixing.downmix = false;
207 config.delay.capture_alignment_mixing.adaptive_selection = false;
208 for (auto rate : {16000, 32000, 48000}) {
209 std::vector<std::vector<std::vector<float>>> render_block(
210 NumBandsForRate(rate),
211 std::vector<std::vector<float>>(
212 num_render_channels, std::vector<float>(kBlockSize, 0.f)));
213 std::vector<std::vector<std::vector<float>>> capture_block(
214 NumBandsForRate(rate),
215 std::vector<std::vector<float>>(
216 num_capture_channels, std::vector<float>(kBlockSize, 0.f)));
217
218 for (int delay_samples : {-15, -50, -150, -200}) {
219 absl::optional<DelayEstimate> delay_blocks;
220 SCOPED_TRACE(ProduceDebugText(rate, -delay_samples,
221 num_render_channels,
222 num_capture_channels));
223 std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
224 RenderDelayBuffer::Create(config, rate, num_render_channels));
225 std::unique_ptr<RenderDelayController> delay_controller(
226 RenderDelayController::Create(EchoCanceller3Config(), rate,
227 num_capture_channels));
228 DelayBuffer<float> signal_delay_buffer(-delay_samples);
229 for (int k = 0;
230 k < (400 - delay_samples / static_cast<int>(kBlockSize));
231 ++k) {
232 RandomizeSampleVector(&random_generator, capture_block[0][0]);
233 signal_delay_buffer.Delay(capture_block[0][0],
234 render_block[0][0]);
235 render_delay_buffer->Insert(render_block);
236 render_delay_buffer->PrepareCaptureProcessing();
237 delay_blocks = delay_controller->GetDelay(
238 render_delay_buffer->GetDownsampledRenderBuffer(),
239 render_delay_buffer->Delay(), capture_block[0]);
240 }
241
242 ASSERT_FALSE(delay_blocks);
243 }
244 }
245 }
246 }
247 }
248 }
249 }
250
251 // Verifies that the RenderDelayController is able to align the signals for
252 // simple timeshifts between the signals when there is jitter in the API calls.
253 // TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController,DISABLED_AlignmentWithJitter)254 TEST(RenderDelayController, DISABLED_AlignmentWithJitter) {
255 Random random_generator(42U);
256 for (size_t num_capture_channels : {1, 2, 4}) {
257 for (size_t num_render_channels : {1, 2, 8}) {
258 std::vector<std::vector<float>> capture_block(
259 num_capture_channels, std::vector<float>(kBlockSize, 0.f));
260 for (size_t num_matched_filters = 4; num_matched_filters <= 10;
261 num_matched_filters++) {
262 for (auto down_sampling_factor : kDownSamplingFactors) {
263 EchoCanceller3Config config;
264 config.delay.down_sampling_factor = down_sampling_factor;
265 config.delay.num_filters = num_matched_filters;
266 config.delay.capture_alignment_mixing.downmix = false;
267 config.delay.capture_alignment_mixing.adaptive_selection = false;
268
269 for (auto rate : {16000, 32000, 48000}) {
270 std::vector<std::vector<std::vector<float>>> render_block(
271 NumBandsForRate(rate),
272 std::vector<std::vector<float>>(
273 num_render_channels, std::vector<float>(kBlockSize, 0.f)));
274 for (size_t delay_samples : {15, 50, 300, 800}) {
275 absl::optional<DelayEstimate> delay_blocks;
276 SCOPED_TRACE(ProduceDebugText(rate, delay_samples,
277 num_render_channels,
278 num_capture_channels));
279 std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
280 RenderDelayBuffer::Create(config, rate, num_render_channels));
281 std::unique_ptr<RenderDelayController> delay_controller(
282 RenderDelayController::Create(config, rate,
283 num_capture_channels));
284 DelayBuffer<float> signal_delay_buffer(delay_samples);
285 constexpr size_t kMaxTestJitterBlocks = 26;
286 for (size_t j = 0; j < (1000 + delay_samples / kBlockSize) /
287 kMaxTestJitterBlocks +
288 1;
289 ++j) {
290 std::vector<std::vector<std::vector<float>>>
291 capture_block_buffer;
292 for (size_t k = 0; k < (kMaxTestJitterBlocks - 1); ++k) {
293 RandomizeSampleVector(&random_generator, render_block[0][0]);
294 signal_delay_buffer.Delay(render_block[0][0],
295 capture_block[0]);
296 capture_block_buffer.push_back(capture_block);
297 render_delay_buffer->Insert(render_block);
298 }
299 for (size_t k = 0; k < (kMaxTestJitterBlocks - 1); ++k) {
300 render_delay_buffer->PrepareCaptureProcessing();
301 delay_blocks = delay_controller->GetDelay(
302 render_delay_buffer->GetDownsampledRenderBuffer(),
303 render_delay_buffer->Delay(), capture_block_buffer[k]);
304 }
305 }
306
307 constexpr int kDelayHeadroomBlocks = 1;
308 size_t expected_delay_blocks =
309 std::max(0, static_cast<int>(delay_samples / kBlockSize) -
310 kDelayHeadroomBlocks);
311 if (expected_delay_blocks < 2) {
312 expected_delay_blocks = 0;
313 }
314
315 ASSERT_TRUE(delay_blocks);
316 EXPECT_EQ(expected_delay_blocks, delay_blocks->delay);
317 }
318 }
319 }
320 }
321 }
322 }
323 }
324
325 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
326
327 // Verifies the check for the capture signal block size.
TEST(RenderDelayControllerDeathTest,WrongCaptureSize)328 TEST(RenderDelayControllerDeathTest, WrongCaptureSize) {
329 std::vector<std::vector<float>> block(
330 1, std::vector<float>(kBlockSize - 1, 0.f));
331 EchoCanceller3Config config;
332 for (auto rate : {16000, 32000, 48000}) {
333 SCOPED_TRACE(ProduceDebugText(rate));
334 std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
335 RenderDelayBuffer::Create(config, rate, 1));
336 EXPECT_DEATH(
337 std::unique_ptr<RenderDelayController>(
338 RenderDelayController::Create(EchoCanceller3Config(), rate, 1))
339 ->GetDelay(render_delay_buffer->GetDownsampledRenderBuffer(),
340 render_delay_buffer->Delay(), block),
341 "");
342 }
343 }
344
345 // Verifies the check for correct sample rate.
346 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
347 // tests on test bots has been fixed.
TEST(RenderDelayControllerDeathTest,DISABLED_WrongSampleRate)348 TEST(RenderDelayControllerDeathTest, DISABLED_WrongSampleRate) {
349 for (auto rate : {-1, 0, 8001, 16001}) {
350 SCOPED_TRACE(ProduceDebugText(rate));
351 EchoCanceller3Config config;
352 std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
353 RenderDelayBuffer::Create(config, rate, 1));
354 EXPECT_DEATH(
355 std::unique_ptr<RenderDelayController>(
356 RenderDelayController::Create(EchoCanceller3Config(), rate, 1)),
357 "");
358 }
359 }
360
361 #endif
362
363 } // namespace webrtc
364