Add core multi-channel pipeline in AEC3

This CL adds basic the basic pipeline to support multi-channel
processing in AEC3.

Apart from that, it removes the 8 kHz processing support in several
places of the AEC3 code.

Bug: webrtc:10913
Change-Id: If5b75fa325ed0071deea94a7546cb4a7adf22137
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/150332
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29017}
This commit is contained in:
Per Åhgren
2019-08-30 08:54:09 +02:00
committed by Commit Bot
parent 01a49189af
commit f3a197e553
58 changed files with 1846 additions and 1137 deletions

View File

@ -36,11 +36,16 @@ using ::testing::StrictMock;
// Verifies that the basic BlockProcessor functionality works and that the API
// methods are callable.
void RunBasicSetupAndApiCallTest(int sample_rate_hz, int num_iterations) {
std::unique_ptr<BlockProcessor> block_processor(
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
std::vector<std::vector<float>> block(NumBandsForRate(sample_rate_hz),
std::vector<float>(kBlockSize, 1000.f));
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, 1000.f)));
for (int k = 0; k < num_iterations; ++k) {
block_processor->BufferRender(block);
block_processor->ProcessCapture(false, false, &block);
@ -50,43 +55,67 @@ void RunBasicSetupAndApiCallTest(int sample_rate_hz, int num_iterations) {
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
void RunRenderBlockSizeVerificationTest(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));
std::vector<std::vector<float>> block(
NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));
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->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));
std::vector<std::vector<float>> block(
NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));
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, &block), "");
}
void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
constexpr size_t kNumRenderChannels = 1;
constexpr size_t kNumCaptureChannels = 1;
const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
? NumBandsForRate(sample_rate_hz) + 1
: 1;
std::unique_ptr<BlockProcessor> block_processor(
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
std::vector<std::vector<float>> block(wrong_num_bands,
std::vector<float>(kBlockSize, 0.f));
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)));
EXPECT_DEATH(block_processor->BufferRender(block), "");
}
void RunCaptureNumBandsVerificationTest(int sample_rate_hz) {
constexpr size_t kNumRenderChannels = 1;
constexpr size_t kNumCaptureChannels = 1;
const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
? NumBandsForRate(sample_rate_hz) + 1
: 1;
std::unique_ptr<BlockProcessor> block_processor(
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
std::vector<std::vector<float>> block(wrong_num_bands,
std::vector<float>(kBlockSize, 0.f));
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)));
EXPECT_DEATH(block_processor->ProcessCapture(false, false, &block), "");
}
@ -104,17 +133,19 @@ std::string ProduceDebugText(int sample_rate_hz) {
// the render delay buffer inside block processor.
// TODO(peah): Activate the unittest once the required code has been landed.
TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
constexpr size_t kNumRenderChannels = 1;
constexpr size_t kNumCaptureChannels = 1;
constexpr size_t kNumBlocks = 310;
constexpr size_t kDelayInSamples = 640;
constexpr size_t kDelayHeadroom = 1;
constexpr size_t kDelayInBlocks =
kDelayInSamples / kBlockSize - kDelayHeadroom;
Random random_generator(42U);
for (auto rate : {8000, 16000, 32000, 48000}) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate));
std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
render_delay_buffer_mock(
new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate));
new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate, 1));
EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
.Times(kNumBlocks)
.WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
@ -125,16 +156,21 @@ TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
.Times(kNumBlocks + 1)
.WillRepeatedly(Return(0));
std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
EchoCanceller3Config(), rate, std::move(render_delay_buffer_mock)));
EchoCanceller3Config(), rate, kNumRenderChannels, kNumCaptureChannels,
std::move(render_delay_buffer_mock)));
std::vector<std::vector<float>> render_block(
NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
std::vector<std::vector<float>> capture_block(
NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
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)));
DelayBuffer<float> signal_delay_buffer(kDelayInSamples);
for (size_t k = 0; k < kNumBlocks; ++k) {
RandomizeSampleVector(&random_generator, render_block[0]);
signal_delay_buffer.Delay(render_block[0], capture_block[0]);
RandomizeSampleVector(&random_generator, render_block[0][0]);
signal_delay_buffer.Delay(render_block[0][0], capture_block[0][0]);
block_processor->BufferRender(render_block);
block_processor->ProcessCapture(false, false, &capture_block);
}
@ -144,12 +180,15 @@ TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
// Verifies that BlockProcessor submodules are called in a proper manner.
TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
constexpr size_t kNumBlocks = 310;
constexpr size_t kNumRenderChannels = 1;
constexpr size_t kNumCaptureChannels = 1;
Random random_generator(42U);
for (auto rate : {8000, 16000, 32000, 48000}) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate));
std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
render_delay_buffer_mock(
new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate));
new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate, 1));
std::unique_ptr<
::testing::StrictMock<webrtc::test::MockRenderDelayController>>
render_delay_controller_mock(
@ -174,17 +213,22 @@ TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
.Times(kNumBlocks);
std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
EchoCanceller3Config(), rate, std::move(render_delay_buffer_mock),
EchoCanceller3Config(), rate, kNumRenderChannels, kNumCaptureChannels,
std::move(render_delay_buffer_mock),
std::move(render_delay_controller_mock), std::move(echo_remover_mock)));
std::vector<std::vector<float>> render_block(
NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
std::vector<std::vector<float>> capture_block(
NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
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)));
DelayBuffer<float> signal_delay_buffer(640);
for (size_t k = 0; k < kNumBlocks; ++k) {
RandomizeSampleVector(&random_generator, render_block[0]);
signal_delay_buffer.Delay(render_block[0], capture_block[0]);
RandomizeSampleVector(&random_generator, render_block[0][0]);
signal_delay_buffer.Delay(render_block[0][0], capture_block[0][0]);
block_processor->BufferRender(render_block);
block_processor->ProcessCapture(false, false, &capture_block);
block_processor->UpdateEchoLeakageStatus(false);
@ -193,7 +237,7 @@ TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
}
TEST(BlockProcessor, BasicSetupAndApiCalls) {
for (auto rate : {8000, 16000, 32000, 48000}) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate));
RunBasicSetupAndApiCallTest(rate, 1);
}
@ -207,21 +251,21 @@ TEST(BlockProcessor, TestLongerCall) {
// TODO(gustaf): Re-enable the test once the issue with memory leaks during
// DEATH tests on test bots has been fixed.
TEST(BlockProcessor, DISABLED_VerifyRenderBlockSizeCheck) {
for (auto rate : {8000, 16000, 32000, 48000}) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate));
RunRenderBlockSizeVerificationTest(rate);
}
}
TEST(BlockProcessor, VerifyCaptureBlockSizeCheck) {
for (auto rate : {8000, 16000, 32000, 48000}) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate));
RunCaptureBlockSizeVerificationTest(rate);
}
}
TEST(BlockProcessor, VerifyRenderNumBandsCheck) {
for (auto rate : {8000, 16000, 32000, 48000}) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate));
RunRenderNumBandsVerificationTest(rate);
}
@ -230,7 +274,7 @@ TEST(BlockProcessor, VerifyRenderNumBandsCheck) {
// TODO(peah): Verify the check for correct number of bands in the capture
// signal.
TEST(BlockProcessor, VerifyCaptureNumBandsCheck) {
for (auto rate : {8000, 16000, 32000, 48000}) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate));
RunCaptureNumBandsVerificationTest(rate);
}
@ -239,7 +283,7 @@ TEST(BlockProcessor, VerifyCaptureNumBandsCheck) {
// Verifiers that the verification for null ProcessCapture input works.
TEST(BlockProcessor, NullProcessCaptureParameter) {
EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
BlockProcessor::Create(EchoCanceller3Config(), 8000))
BlockProcessor::Create(EchoCanceller3Config(), 16000, 1, 1))
->ProcessCapture(false, false, nullptr),
"");
}
@ -249,7 +293,7 @@ TEST(BlockProcessor, NullProcessCaptureParameter) {
// tests on test bots has been fixed.
TEST(BlockProcessor, DISABLED_WrongSampleRate) {
EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
BlockProcessor::Create(EchoCanceller3Config(), 8001)),
BlockProcessor::Create(EchoCanceller3Config(), 8001, 1, 1)),
"");
}