tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

block_processor_unittest.cc (15252B)


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