AEC3: Added multi-channel support for the capture delay functionality

This CL adds the missing support for multi-channel in the code that
provides an optional and configurable delay to be added to the
microphone signal.

The CL also makes the creation of the delay object conditional on the
need for that support (this is important since this adds a significant
heap memory footprint)

Bug: webrtc:11314,chromium:1045910
Change-Id: I92d577e31af830945fe9d5ca2032000aad4266be
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/167525
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30392}
This commit is contained in:
Per Åhgren
2020-01-28 15:38:41 +01:00
committed by Commit Bot
parent 4a5dab00ae
commit 260c788d77
5 changed files with 86 additions and 46 deletions

View File

@ -47,37 +47,54 @@ std::string ProduceDebugText(int sample_rate_hz, size_t delay) {
} // namespace
class BlockDelayBufferTest
: public ::testing::Test,
public ::testing::WithParamInterface<std::tuple<size_t, int, size_t>> {};
INSTANTIATE_TEST_SUITE_P(
ParameterCombinations,
BlockDelayBufferTest,
::testing::Combine(::testing::Values(0, 1, 27, 160, 4321, 7021),
::testing::Values(16000, 32000, 48000),
::testing::Values(1, 2, 4)));
// Verifies that the correct signal delay is achived.
TEST(BlockDelayBuffer, CorrectDelayApplied) {
for (size_t delay : {0, 1, 27, 160, 4321, 7021}) {
for (auto rate : {16000, 32000, 48000}) {
SCOPED_TRACE(ProduceDebugText(rate, delay));
size_t num_bands = NumBandsForRate(rate);
size_t subband_frame_length = 160;
TEST_P(BlockDelayBufferTest, CorrectDelayApplied) {
const size_t delay = std::get<0>(GetParam());
const int rate = std::get<1>(GetParam());
const size_t num_channels = std::get<2>(GetParam());
BlockDelayBuffer delay_buffer(num_bands, subband_frame_length, delay);
SCOPED_TRACE(ProduceDebugText(rate, delay));
size_t num_bands = NumBandsForRate(rate);
size_t subband_frame_length = 160;
static constexpr size_t kNumFramesToProcess = 20;
for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
++frame_index) {
AudioBuffer audio_buffer(rate, 1, rate, 1, rate, 1);
if (rate > 16000) {
audio_buffer.SplitIntoFrequencyBands();
}
size_t first_sample_index = frame_index * subband_frame_length;
PopulateInputFrame(subband_frame_length, num_bands, first_sample_index,
&audio_buffer.split_bands(0)[0]);
delay_buffer.DelaySignal(&audio_buffer);
BlockDelayBuffer delay_buffer(num_channels, num_bands, subband_frame_length,
delay);
for (size_t k = 0; k < num_bands; ++k) {
size_t sample_index = first_sample_index;
for (size_t i = 0; i < subband_frame_length; ++i, ++sample_index) {
if (sample_index < delay) {
EXPECT_EQ(0.f, audio_buffer.split_bands(0)[k][i]);
} else {
EXPECT_EQ(SampleValue(sample_index - delay),
audio_buffer.split_bands(0)[k][i]);
}
static constexpr size_t kNumFramesToProcess = 20;
for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
++frame_index) {
AudioBuffer audio_buffer(rate, num_channels, rate, num_channels, rate,
num_channels);
if (rate > 16000) {
audio_buffer.SplitIntoFrequencyBands();
}
size_t first_sample_index = frame_index * subband_frame_length;
for (size_t ch = 0; ch < num_channels; ++ch) {
PopulateInputFrame(subband_frame_length, num_bands, first_sample_index,
&audio_buffer.split_bands(ch)[0]);
}
delay_buffer.DelaySignal(&audio_buffer);
for (size_t ch = 0; ch < num_channels; ++ch) {
for (size_t band = 0; band < num_bands; ++band) {
size_t sample_index = first_sample_index;
for (size_t i = 0; i < subband_frame_length; ++i, ++sample_index) {
if (sample_index < delay) {
EXPECT_EQ(0.f, audio_buffer.split_bands(ch)[band][i]);
} else {
EXPECT_EQ(SampleValue(sample_index - delay),
audio_buffer.split_bands(ch)[band][i]);
}
}
}