xref: /aosp_15_r20/external/webrtc/modules/audio_processing/aec3/render_delay_controller_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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     Block block(/*num_bands=1*/ 1, /*num_channels=*/1);
57     EchoCanceller3Config config;
58     for (size_t num_matched_filters = 4; num_matched_filters <= 10;
59          num_matched_filters++) {
60       for (auto down_sampling_factor : kDownSamplingFactors) {
61         config.delay.down_sampling_factor = down_sampling_factor;
62         config.delay.num_filters = num_matched_filters;
63         for (auto rate : {16000, 32000, 48000}) {
64           SCOPED_TRACE(ProduceDebugText(rate));
65           std::unique_ptr<RenderDelayBuffer> delay_buffer(
66               RenderDelayBuffer::Create(config, rate, num_render_channels));
67           std::unique_ptr<RenderDelayController> delay_controller(
68               RenderDelayController::Create(config, rate,
69                                             /*num_capture_channels*/ 1));
70           for (size_t k = 0; k < 100; ++k) {
71             auto delay = delay_controller->GetDelay(
72                 delay_buffer->GetDownsampledRenderBuffer(),
73                 delay_buffer->Delay(), block);
74             EXPECT_FALSE(delay->delay);
75           }
76         }
77       }
78     }
79   }
80 }
81 
82 // Verifies the basic API call sequence.
83 // TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController,DISABLED_BasicApiCalls)84 TEST(RenderDelayController, DISABLED_BasicApiCalls) {
85   for (size_t num_capture_channels : {1, 2, 4}) {
86     for (size_t num_render_channels : {1, 2, 8}) {
87       Block capture_block(/*num_bands=*/1, num_capture_channels);
88       absl::optional<DelayEstimate> delay_blocks;
89       for (size_t num_matched_filters = 4; num_matched_filters <= 10;
90            num_matched_filters++) {
91         for (auto down_sampling_factor : kDownSamplingFactors) {
92           EchoCanceller3Config config;
93           config.delay.down_sampling_factor = down_sampling_factor;
94           config.delay.num_filters = num_matched_filters;
95           config.delay.capture_alignment_mixing.downmix = false;
96           config.delay.capture_alignment_mixing.adaptive_selection = false;
97 
98           for (auto rate : {16000, 32000, 48000}) {
99             Block render_block(NumBandsForRate(rate), num_render_channels);
100             std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
101                 RenderDelayBuffer::Create(config, rate, num_render_channels));
102             std::unique_ptr<RenderDelayController> delay_controller(
103                 RenderDelayController::Create(EchoCanceller3Config(), rate,
104                                               num_capture_channels));
105             for (size_t k = 0; k < 10; ++k) {
106               render_delay_buffer->Insert(render_block);
107               render_delay_buffer->PrepareCaptureProcessing();
108 
109               delay_blocks = delay_controller->GetDelay(
110                   render_delay_buffer->GetDownsampledRenderBuffer(),
111                   render_delay_buffer->Delay(), capture_block);
112             }
113             EXPECT_TRUE(delay_blocks);
114             EXPECT_FALSE(delay_blocks->delay);
115           }
116         }
117       }
118     }
119   }
120 }
121 
122 // Verifies that the RenderDelayController is able to align the signals for
123 // simple timeshifts between the signals.
124 // TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController,DISABLED_Alignment)125 TEST(RenderDelayController, DISABLED_Alignment) {
126   Random random_generator(42U);
127   for (size_t num_capture_channels : {1, 2, 4}) {
128     Block capture_block(/*num_bands=*/1, num_capture_channels);
129     for (size_t num_matched_filters = 4; num_matched_filters <= 10;
130          num_matched_filters++) {
131       for (auto down_sampling_factor : kDownSamplingFactors) {
132         EchoCanceller3Config config;
133         config.delay.down_sampling_factor = down_sampling_factor;
134         config.delay.num_filters = num_matched_filters;
135         config.delay.capture_alignment_mixing.downmix = false;
136         config.delay.capture_alignment_mixing.adaptive_selection = false;
137 
138         for (size_t num_render_channels : {1, 2, 8}) {
139           for (auto rate : {16000, 32000, 48000}) {
140             Block render_block(NumBandsForRate(rate), num_render_channels);
141 
142             for (size_t delay_samples : {15, 50, 150, 200, 800, 4000}) {
143               absl::optional<DelayEstimate> delay_blocks;
144               SCOPED_TRACE(ProduceDebugText(rate, delay_samples,
145                                             num_render_channels,
146                                             num_capture_channels));
147               std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
148                   RenderDelayBuffer::Create(config, rate, num_render_channels));
149               std::unique_ptr<RenderDelayController> delay_controller(
150                   RenderDelayController::Create(config, rate,
151                                                 num_capture_channels));
152               DelayBuffer<float> signal_delay_buffer(delay_samples);
153               for (size_t k = 0; k < (400 + delay_samples / kBlockSize); ++k) {
154                 for (int band = 0; band < render_block.NumBands(); ++band) {
155                   for (int channel = 0; channel < render_block.NumChannels();
156                        ++channel) {
157                     RandomizeSampleVector(&random_generator,
158                                           render_block.View(band, channel));
159                   }
160                 }
161                 signal_delay_buffer.Delay(
162                     render_block.View(/*band=*/0, /*channel=*/0),
163                     capture_block.View(/*band=*/0, /*channel=*/0));
164                 render_delay_buffer->Insert(render_block);
165                 render_delay_buffer->PrepareCaptureProcessing();
166                 delay_blocks = delay_controller->GetDelay(
167                     render_delay_buffer->GetDownsampledRenderBuffer(),
168                     render_delay_buffer->Delay(), capture_block);
169               }
170               ASSERT_TRUE(!!delay_blocks);
171 
172               constexpr int kDelayHeadroomBlocks = 1;
173               size_t expected_delay_blocks =
174                   std::max(0, static_cast<int>(delay_samples / kBlockSize) -
175                                   kDelayHeadroomBlocks);
176 
177               EXPECT_EQ(expected_delay_blocks, delay_blocks->delay);
178             }
179           }
180         }
181       }
182     }
183   }
184 }
185 
186 // Verifies that the RenderDelayController is able to properly handle noncausal
187 // delays.
188 // TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController,DISABLED_NonCausalAlignment)189 TEST(RenderDelayController, DISABLED_NonCausalAlignment) {
190   Random random_generator(42U);
191   for (size_t num_capture_channels : {1, 2, 4}) {
192     for (size_t num_render_channels : {1, 2, 8}) {
193       for (size_t num_matched_filters = 4; num_matched_filters <= 10;
194            num_matched_filters++) {
195         for (auto down_sampling_factor : kDownSamplingFactors) {
196           EchoCanceller3Config config;
197           config.delay.down_sampling_factor = down_sampling_factor;
198           config.delay.num_filters = num_matched_filters;
199           config.delay.capture_alignment_mixing.downmix = false;
200           config.delay.capture_alignment_mixing.adaptive_selection = false;
201           for (auto rate : {16000, 32000, 48000}) {
202             Block render_block(NumBandsForRate(rate), num_render_channels);
203             Block capture_block(NumBandsForRate(rate), num_capture_channels);
204 
205             for (int delay_samples : {-15, -50, -150, -200}) {
206               absl::optional<DelayEstimate> delay_blocks;
207               SCOPED_TRACE(ProduceDebugText(rate, -delay_samples,
208                                             num_render_channels,
209                                             num_capture_channels));
210               std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
211                   RenderDelayBuffer::Create(config, rate, num_render_channels));
212               std::unique_ptr<RenderDelayController> delay_controller(
213                   RenderDelayController::Create(EchoCanceller3Config(), rate,
214                                                 num_capture_channels));
215               DelayBuffer<float> signal_delay_buffer(-delay_samples);
216               for (int k = 0;
217                    k < (400 - delay_samples / static_cast<int>(kBlockSize));
218                    ++k) {
219                 RandomizeSampleVector(
220                     &random_generator,
221                     capture_block.View(/*band=*/0, /*channel=*/0));
222                 signal_delay_buffer.Delay(
223                     capture_block.View(/*band=*/0, /*channel=*/0),
224                     render_block.View(/*band=*/0, /*channel=*/0));
225                 render_delay_buffer->Insert(render_block);
226                 render_delay_buffer->PrepareCaptureProcessing();
227                 delay_blocks = delay_controller->GetDelay(
228                     render_delay_buffer->GetDownsampledRenderBuffer(),
229                     render_delay_buffer->Delay(), capture_block);
230               }
231 
232               ASSERT_FALSE(delay_blocks);
233             }
234           }
235         }
236       }
237     }
238   }
239 }
240 
241 // Verifies that the RenderDelayController is able to align the signals for
242 // simple timeshifts between the signals when there is jitter in the API calls.
243 // TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController,DISABLED_AlignmentWithJitter)244 TEST(RenderDelayController, DISABLED_AlignmentWithJitter) {
245   Random random_generator(42U);
246   for (size_t num_capture_channels : {1, 2, 4}) {
247     for (size_t num_render_channels : {1, 2, 8}) {
248       Block capture_block(
249           /*num_bands=*/1, num_capture_channels);
250       for (size_t num_matched_filters = 4; num_matched_filters <= 10;
251            num_matched_filters++) {
252         for (auto down_sampling_factor : kDownSamplingFactors) {
253           EchoCanceller3Config config;
254           config.delay.down_sampling_factor = down_sampling_factor;
255           config.delay.num_filters = num_matched_filters;
256           config.delay.capture_alignment_mixing.downmix = false;
257           config.delay.capture_alignment_mixing.adaptive_selection = false;
258 
259           for (auto rate : {16000, 32000, 48000}) {
260             Block render_block(NumBandsForRate(rate), num_render_channels);
261             for (size_t delay_samples : {15, 50, 300, 800}) {
262               absl::optional<DelayEstimate> delay_blocks;
263               SCOPED_TRACE(ProduceDebugText(rate, delay_samples,
264                                             num_render_channels,
265                                             num_capture_channels));
266               std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
267                   RenderDelayBuffer::Create(config, rate, num_render_channels));
268               std::unique_ptr<RenderDelayController> delay_controller(
269                   RenderDelayController::Create(config, rate,
270                                                 num_capture_channels));
271               DelayBuffer<float> signal_delay_buffer(delay_samples);
272               constexpr size_t kMaxTestJitterBlocks = 26;
273               for (size_t j = 0; j < (1000 + delay_samples / kBlockSize) /
274                                              kMaxTestJitterBlocks +
275                                          1;
276                    ++j) {
277                 std::vector<Block> capture_block_buffer;
278                 for (size_t k = 0; k < (kMaxTestJitterBlocks - 1); ++k) {
279                   RandomizeSampleVector(
280                       &random_generator,
281                       render_block.View(/*band=*/0, /*channel=*/0));
282                   signal_delay_buffer.Delay(
283                       render_block.View(/*band=*/0, /*channel=*/0),
284                       capture_block.View(/*band=*/0, /*channel=*/0));
285                   capture_block_buffer.push_back(capture_block);
286                   render_delay_buffer->Insert(render_block);
287                 }
288                 for (size_t k = 0; k < (kMaxTestJitterBlocks - 1); ++k) {
289                   render_delay_buffer->PrepareCaptureProcessing();
290                   delay_blocks = delay_controller->GetDelay(
291                       render_delay_buffer->GetDownsampledRenderBuffer(),
292                       render_delay_buffer->Delay(), capture_block_buffer[k]);
293                 }
294               }
295 
296               constexpr int kDelayHeadroomBlocks = 1;
297               size_t expected_delay_blocks =
298                   std::max(0, static_cast<int>(delay_samples / kBlockSize) -
299                                   kDelayHeadroomBlocks);
300               if (expected_delay_blocks < 2) {
301                 expected_delay_blocks = 0;
302               }
303 
304               ASSERT_TRUE(delay_blocks);
305               EXPECT_EQ(expected_delay_blocks, delay_blocks->delay);
306             }
307           }
308         }
309       }
310     }
311   }
312 }
313 
314 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
315 
316 // Verifies the check for correct sample rate.
317 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
318 // tests on test bots has been fixed.
TEST(RenderDelayControllerDeathTest,DISABLED_WrongSampleRate)319 TEST(RenderDelayControllerDeathTest, DISABLED_WrongSampleRate) {
320   for (auto rate : {-1, 0, 8001, 16001}) {
321     SCOPED_TRACE(ProduceDebugText(rate));
322     EchoCanceller3Config config;
323     std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
324         RenderDelayBuffer::Create(config, rate, 1));
325     EXPECT_DEATH(
326         std::unique_ptr<RenderDelayController>(
327             RenderDelayController::Create(EchoCanceller3Config(), rate, 1)),
328         "");
329   }
330 }
331 
332 #endif
333 
334 }  // namespace webrtc
335