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