AEC3: 'Block' class

This change adds a Block class to reduce the need for std::vector<std::vector<std::vector<float>>>. This make the code
easier to read and less error prone.

It also enables future changes to the underlying data structure of a
block. For instance, the data of all bands and channels could be stored
in a single vector.

The change has been verified to be bit-exact.

Bug: webrtc:14089
Change-Id: Ied9a78124c0bbafe0e912017aef91f7c311de2ae
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262252
Reviewed-by: Per Åhgren <peah@webrtc.org>
Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36968}
This commit is contained in:
Gustaf Ullberg
2022-05-23 10:39:53 +02:00
committed by WebRTC LUCI CQ
parent 742714870a
commit d3ead1a942
62 changed files with 663 additions and 937 deletions

View File

@ -43,10 +43,7 @@ void RunBasicSetupAndApiCallTest(int sample_rate_hz, int num_iterations) {
std::unique_ptr<BlockProcessor> block_processor(
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
kNumRenderChannels, kNumCaptureChannels));
std::vector<std::vector<std::vector<float>>> block(
NumBandsForRate(sample_rate_hz),
std::vector<std::vector<float>>(kNumRenderChannels,
std::vector<float>(kBlockSize, 1000.f)));
Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels, 1000.f);
for (int k = 0; k < num_iterations; ++k) {
block_processor->BufferRender(block);
block_processor->ProcessCapture(false, false, nullptr, &block);
@ -62,30 +59,11 @@ void RunRenderBlockSizeVerificationTest(int sample_rate_hz) {
std::unique_ptr<BlockProcessor> block_processor(
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
kNumRenderChannels, kNumCaptureChannels));
std::vector<std::vector<std::vector<float>>> block(
NumBandsForRate(sample_rate_hz),
std::vector<std::vector<float>>(kNumRenderChannels,
std::vector<float>(kBlockSize - 1, 0.f)));
Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels);
EXPECT_DEATH(block_processor->BufferRender(block), "");
}
void RunCaptureBlockSizeVerificationTest(int sample_rate_hz) {
constexpr size_t kNumRenderChannels = 1;
constexpr size_t kNumCaptureChannels = 1;
std::unique_ptr<BlockProcessor> block_processor(
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
kNumRenderChannels, kNumCaptureChannels));
std::vector<std::vector<std::vector<float>>> block(
NumBandsForRate(sample_rate_hz),
std::vector<std::vector<float>>(kNumRenderChannels,
std::vector<float>(kBlockSize - 1, 0.f)));
EXPECT_DEATH(block_processor->ProcessCapture(false, false, nullptr, &block),
"");
}
void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
constexpr size_t kNumRenderChannels = 1;
constexpr size_t kNumCaptureChannels = 1;
@ -96,10 +74,7 @@ void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
std::unique_ptr<BlockProcessor> block_processor(
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
kNumRenderChannels, kNumCaptureChannels));
std::vector<std::vector<std::vector<float>>> block(
wrong_num_bands,
std::vector<std::vector<float>>(kNumRenderChannels,
std::vector<float>(kBlockSize, 0.f)));
Block block(wrong_num_bands, kNumRenderChannels);
EXPECT_DEATH(block_processor->BufferRender(block), "");
}
@ -114,10 +89,7 @@ void RunCaptureNumBandsVerificationTest(int sample_rate_hz) {
std::unique_ptr<BlockProcessor> block_processor(
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
kNumRenderChannels, kNumCaptureChannels));
std::vector<std::vector<std::vector<float>>> block(
wrong_num_bands,
std::vector<std::vector<float>>(kNumRenderChannels,
std::vector<float>(kBlockSize, 0.f)));
Block block(wrong_num_bands, kNumRenderChannels);
EXPECT_DEATH(block_processor->ProcessCapture(false, false, nullptr, &block),
"");
@ -170,18 +142,14 @@ TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
EchoCanceller3Config(), rate, kNumRenderChannels, kNumCaptureChannels,
std::move(render_delay_buffer_mock)));
std::vector<std::vector<std::vector<float>>> render_block(
NumBandsForRate(rate),
std::vector<std::vector<float>>(kNumRenderChannels,
std::vector<float>(kBlockSize, 0.f)));
std::vector<std::vector<std::vector<float>>> capture_block(
NumBandsForRate(rate),
std::vector<std::vector<float>>(kNumCaptureChannels,
std::vector<float>(kBlockSize, 0.f)));
Block render_block(NumBandsForRate(rate), kNumRenderChannels);
Block capture_block(NumBandsForRate(rate), kNumCaptureChannels);
DelayBuffer<float> signal_delay_buffer(kDelayInSamples);
for (size_t k = 0; k < kNumBlocks; ++k) {
RandomizeSampleVector(&random_generator, render_block[0][0]);
signal_delay_buffer.Delay(render_block[0][0], capture_block[0][0]);
RandomizeSampleVector(&random_generator,
render_block.View(/*band=*/0, /*capture=*/0));
signal_delay_buffer.Delay(render_block.View(/*band=*/0, /*capture=*/0),
capture_block.View(/*band=*/0, /*capture=*/0));
block_processor->BufferRender(render_block);
block_processor->ProcessCapture(false, false, nullptr, &capture_block);
}
@ -228,18 +196,14 @@ TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
std::move(render_delay_buffer_mock),
std::move(render_delay_controller_mock), std::move(echo_remover_mock)));
std::vector<std::vector<std::vector<float>>> render_block(
NumBandsForRate(rate),
std::vector<std::vector<float>>(kNumRenderChannels,
std::vector<float>(kBlockSize, 0.f)));
std::vector<std::vector<std::vector<float>>> capture_block(
NumBandsForRate(rate),
std::vector<std::vector<float>>(kNumCaptureChannels,
std::vector<float>(kBlockSize, 0.f)));
Block render_block(NumBandsForRate(rate), kNumRenderChannels);
Block capture_block(NumBandsForRate(rate), kNumCaptureChannels);
DelayBuffer<float> signal_delay_buffer(640);
for (size_t k = 0; k < kNumBlocks; ++k) {
RandomizeSampleVector(&random_generator, render_block[0][0]);
signal_delay_buffer.Delay(render_block[0][0], capture_block[0][0]);
RandomizeSampleVector(&random_generator,
render_block.View(/*band=*/0, /*capture=*/0));
signal_delay_buffer.Delay(render_block.View(/*band=*/0, /*capture=*/0),
capture_block.View(/*band=*/0, /*capture=*/0));
block_processor->BufferRender(render_block);
block_processor->ProcessCapture(false, false, nullptr, &capture_block);
block_processor->UpdateEchoLeakageStatus(false);
@ -268,13 +232,6 @@ TEST(BlockProcessorDeathTest, DISABLED_VerifyRenderBlockSizeCheck) {
}
}
TEST(BlockProcessorDeathTest, VerifyCaptureBlockSizeCheck) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate));
RunCaptureBlockSizeVerificationTest(rate);
}
}
TEST(BlockProcessorDeathTest, VerifyRenderNumBandsCheck) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate));
@ -333,14 +290,8 @@ TEST(BlockProcessor, ExternalDelayAppliedCorrectlyWithInitialCaptureCalls) {
std::move(delay_buffer), /*delay_controller=*/nullptr,
std::move(echo_remover_mock)));
std::vector<std::vector<std::vector<float>>> render_block(
NumBandsForRate(kSampleRateHz),
std::vector<std::vector<float>>(kNumRenderChannels,
std::vector<float>(kBlockSize, 0.f)));
std::vector<std::vector<std::vector<float>>> capture_block(
NumBandsForRate(kSampleRateHz),
std::vector<std::vector<float>>(kNumCaptureChannels,
std::vector<float>(kBlockSize, 0.f)));
Block render_block(NumBandsForRate(kSampleRateHz), kNumRenderChannels);
Block capture_block(NumBandsForRate(kSampleRateHz), kNumCaptureChannels);
// Process...
// - 10 capture calls, where no render data is available,
@ -354,11 +305,12 @@ TEST(BlockProcessor, ExternalDelayAppliedCorrectlyWithInitialCaptureCalls) {
int render_call_counter = 0;
for (size_t k = 0; k < 10; ++k) {
FillSampleVector(++capture_call_counter, kDelayInBlocks,
capture_block[0][0]);
capture_block.View(/*band=*/0, /*capture=*/0));
block_processor->ProcessCapture(false, false, nullptr, &capture_block);
}
for (size_t k = 0; k < 10; ++k) {
FillSampleVector(++render_call_counter, 0, render_block[0][0]);
FillSampleVector(++render_call_counter, 0,
render_block.View(/*band=*/0, /*capture=*/0));
block_processor->BufferRender(render_block);
}
@ -367,19 +319,22 @@ TEST(BlockProcessor, ExternalDelayAppliedCorrectlyWithInitialCaptureCalls) {
[](EchoPathVariability /*echo_path_variability*/,
bool /*capture_signal_saturation*/,
const absl::optional<DelayEstimate>& /*external_delay*/,
RenderBuffer* render_buffer,
std::vector<std::vector<std::vector<float>>>* /*linear_output*/,
std::vector<std::vector<std::vector<float>>>* capture) {
RenderBuffer* render_buffer, Block* /*linear_output*/,
Block* capture) {
const auto& render = render_buffer->Block(0);
const auto render_view = render.View(/*band=*/0, /*channel=*/0);
const auto capture_view = capture->View(/*band=*/0, /*channel=*/0);
for (size_t i = 0; i < kBlockSize; ++i) {
EXPECT_FLOAT_EQ(render[0][0][i], (*capture)[0][0][i]);
EXPECT_FLOAT_EQ(render_view[i], capture_view[i]);
}
});
FillSampleVector(++capture_call_counter, kDelayInBlocks, capture_block[0][0]);
FillSampleVector(++capture_call_counter, kDelayInBlocks,
capture_block.View(/*band=*/0, /*capture=*/0));
block_processor->ProcessCapture(false, false, nullptr, &capture_block);
FillSampleVector(++capture_call_counter, kDelayInBlocks, capture_block[0][0]);
FillSampleVector(++capture_call_counter, kDelayInBlocks,
capture_block.View(/*band=*/0, /*capture=*/0));
block_processor->ProcessCapture(false, false, nullptr, &capture_block);
}