• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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