Removed usage of the the redundant the render alignment headroom in AEC3
Bug: webrtc:8671 Change-Id: I1b7b1bc2f4677bbd375fc206c166b4b9fed3efce Reviewed-on: https://webrtc-review.googlesource.com/35220 Commit-Queue: Per Åhgren <peah@webrtc.org> Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org> Cr-Commit-Position: refs/heads/master@{#21392}
This commit is contained in:
@ -389,8 +389,8 @@ TEST(AdaptiveFirFilter, FilterAndAdapt) {
|
||||
aec_state.HandleEchoPathChange(EchoPathVariability(
|
||||
false, EchoPathVariability::DelayAdjustment::kNone, false));
|
||||
aec_state.Update(filter.FilterFrequencyResponse(),
|
||||
filter.FilterImpulseResponse(), true, rtc::nullopt,
|
||||
*render_buffer, E2_main, Y2, x[0], s, false);
|
||||
filter.FilterImpulseResponse(), true, *render_buffer,
|
||||
E2_main, Y2, x[0], s, false);
|
||||
}
|
||||
// Verify that the filter is able to perform well.
|
||||
EXPECT_LT(1000 * std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
|
||||
|
@ -109,7 +109,6 @@ void AecState::Update(
|
||||
adaptive_filter_frequency_response,
|
||||
const std::vector<float>& adaptive_filter_impulse_response,
|
||||
bool converged_filter,
|
||||
const rtc::Optional<size_t>& external_delay_samples,
|
||||
const RenderBuffer& render_buffer,
|
||||
const std::array<float, kFftLengthBy2Plus1>& E2_main,
|
||||
const std::array<float, kFftLengthBy2Plus1>& Y2,
|
||||
@ -134,12 +133,6 @@ void AecState::Update(
|
||||
// Estimate delays.
|
||||
filter_delay_ = EstimateFilterDelay(adaptive_filter_frequency_response);
|
||||
|
||||
// TODO(peah): Remove the dependency on the external delay.
|
||||
external_delay_ =
|
||||
external_delay_samples
|
||||
? rtc::Optional<size_t>(*external_delay_samples / kBlockSize)
|
||||
: rtc::nullopt;
|
||||
|
||||
// Update the ERL and ERLE measures.
|
||||
if (converged_filter && capture_block_counter_ >= 2 * kNumBlocksPerSecond) {
|
||||
const auto& X2 = render_buffer.Spectrum(*filter_delay_);
|
||||
@ -165,8 +158,7 @@ void AecState::Update(
|
||||
usable_linear_estimate_ =
|
||||
!echo_saturation_ &&
|
||||
(converged_filter || filter_has_had_time_to_converge_) &&
|
||||
capture_block_counter_ >= 2 * kNumBlocksPerSecond && external_delay_ &&
|
||||
!TransparentMode();
|
||||
capture_block_counter_ >= 2 * kNumBlocksPerSecond && !TransparentMode();
|
||||
|
||||
// After an amount of active render samples for which an echo should have been
|
||||
// detected in the capture signal if the ERL was not infinite, flag that a
|
||||
|
@ -64,9 +64,6 @@ class AecState {
|
||||
// Returns the delay estimate based on the linear filter.
|
||||
rtc::Optional<size_t> FilterDelay() const { return filter_delay_; }
|
||||
|
||||
// Returns the externally provided delay.
|
||||
rtc::Optional<size_t> ExternalDelay() const { return external_delay_; }
|
||||
|
||||
// Returns whether the capture signal is saturated.
|
||||
bool SaturatedCapture() const { return capture_signal_saturation_; }
|
||||
|
||||
@ -111,7 +108,6 @@ class AecState {
|
||||
adaptive_filter_frequency_response,
|
||||
const std::vector<float>& adaptive_filter_impulse_response,
|
||||
bool converged_filter,
|
||||
const rtc::Optional<size_t>& external_delay_samples,
|
||||
const RenderBuffer& render_buffer,
|
||||
const std::array<float, kFftLengthBy2Plus1>& E2_main,
|
||||
const std::array<float, kFftLengthBy2Plus1>& Y2,
|
||||
@ -156,7 +152,6 @@ class AecState {
|
||||
bool render_received_ = false;
|
||||
size_t force_zero_gain_counter_ = 0;
|
||||
rtc::Optional<size_t> filter_delay_;
|
||||
rtc::Optional<size_t> external_delay_;
|
||||
size_t blocks_since_last_saturation_ = 1000;
|
||||
float reverb_decay_to_test_ = 0.9f;
|
||||
float reverb_decay_candidate_ = 0.f;
|
||||
|
@ -46,17 +46,16 @@ TEST(AecState, NormalUsage) {
|
||||
std::vector<float> impulse_response(
|
||||
GetTimeDomainLength(config.filter.length_blocks), 0.f);
|
||||
|
||||
// Verify that linear AEC usability is false when the filter is diverged and
|
||||
// there is no external delay reported.
|
||||
// Verify that linear AEC usability is false when the filter is diverged.
|
||||
state.Update(diverged_filter_frequency_response, impulse_response, true,
|
||||
rtc::nullopt, *render_delay_buffer->GetRenderBuffer(), E2_main,
|
||||
Y2, x[0], s, false);
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
false);
|
||||
EXPECT_FALSE(state.UsableLinearEstimate());
|
||||
|
||||
// Verify that linear AEC usability is true when the filter is converged
|
||||
std::fill(x[0].begin(), x[0].end(), 101.f);
|
||||
for (int k = 0; k < 3000; ++k) {
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true, 2,
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
false);
|
||||
}
|
||||
@ -66,7 +65,7 @@ TEST(AecState, NormalUsage) {
|
||||
// reported
|
||||
state.HandleEchoPathChange(EchoPathVariability(
|
||||
true, EchoPathVariability::DelayAdjustment::kNone, false));
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true, 2,
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
false);
|
||||
EXPECT_FALSE(state.UsableLinearEstimate());
|
||||
@ -75,25 +74,25 @@ TEST(AecState, NormalUsage) {
|
||||
std::fill(x[0].begin(), x[0].end(), 101.f);
|
||||
state.HandleEchoPathChange(EchoPathVariability(
|
||||
true, EchoPathVariability::DelayAdjustment::kNewDetectedDelay, false));
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true, 2,
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
false);
|
||||
EXPECT_FALSE(state.ActiveRender());
|
||||
|
||||
for (int k = 0; k < 1000; ++k) {
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true, 2,
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
false);
|
||||
}
|
||||
EXPECT_TRUE(state.ActiveRender());
|
||||
|
||||
// Verify that echo leakage is properly reported.
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true, 2,
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
false);
|
||||
EXPECT_FALSE(state.EchoLeakageDetected());
|
||||
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true, 2,
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
true);
|
||||
EXPECT_TRUE(state.EchoLeakageDetected());
|
||||
@ -115,7 +114,7 @@ TEST(AecState, NormalUsage) {
|
||||
|
||||
Y2.fill(10.f * 10000.f * 10000.f);
|
||||
for (size_t k = 0; k < 1000; ++k) {
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true, 2,
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
false);
|
||||
}
|
||||
@ -132,7 +131,7 @@ TEST(AecState, NormalUsage) {
|
||||
E2_main.fill(1.f * 10000.f * 10000.f);
|
||||
Y2.fill(10.f * E2_main[0]);
|
||||
for (size_t k = 0; k < 1000; ++k) {
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true, 2,
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
false);
|
||||
}
|
||||
@ -153,7 +152,7 @@ TEST(AecState, NormalUsage) {
|
||||
E2_main.fill(1.f * 10000.f * 10000.f);
|
||||
Y2.fill(5.f * E2_main[0]);
|
||||
for (size_t k = 0; k < 1000; ++k) {
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true, 2,
|
||||
state.Update(converged_filter_frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0], s,
|
||||
false);
|
||||
}
|
||||
@ -203,7 +202,7 @@ TEST(AecState, ConvergedFilterDelay) {
|
||||
frequency_response[k].fill(100.f);
|
||||
frequency_response[k][0] = 0.f;
|
||||
state.HandleEchoPathChange(echo_path_variability);
|
||||
state.Update(frequency_response, impulse_response, true, rtc::nullopt,
|
||||
state.Update(frequency_response, impulse_response, true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x, s,
|
||||
false);
|
||||
EXPECT_TRUE(k == (kFilterLength - 1) || state.FilterDelay());
|
||||
@ -213,50 +212,4 @@ TEST(AecState, ConvergedFilterDelay) {
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the externally reported delay is properly reported and converted.
|
||||
TEST(AecState, ExternalDelay) {
|
||||
EchoCanceller3Config config;
|
||||
AecState state(config);
|
||||
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
||||
RenderDelayBuffer::Create(config, 3));
|
||||
std::array<float, kFftLengthBy2Plus1> E2_main;
|
||||
std::array<float, kFftLengthBy2Plus1> E2_shadow;
|
||||
std::array<float, kFftLengthBy2Plus1> Y2;
|
||||
std::array<float, kBlockSize> x;
|
||||
std::array<float, kBlockSize> s;
|
||||
s.fill(100.f);
|
||||
E2_main.fill(0.f);
|
||||
E2_shadow.fill(0.f);
|
||||
Y2.fill(0.f);
|
||||
x.fill(0.f);
|
||||
|
||||
std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(
|
||||
config.filter.length_blocks);
|
||||
for (auto& v : frequency_response) {
|
||||
v.fill(0.01f);
|
||||
}
|
||||
|
||||
std::vector<float> impulse_response(
|
||||
GetTimeDomainLength(config.filter.length_blocks), 0.f);
|
||||
|
||||
for (size_t k = 0; k < frequency_response.size() - 1; ++k) {
|
||||
state.HandleEchoPathChange(EchoPathVariability(
|
||||
false, EchoPathVariability::DelayAdjustment::kNone, false));
|
||||
state.Update(frequency_response, impulse_response, true, k * kBlockSize + 5,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x, s,
|
||||
false);
|
||||
EXPECT_TRUE(state.ExternalDelay());
|
||||
EXPECT_EQ(k, state.ExternalDelay());
|
||||
}
|
||||
|
||||
// Verify that the externally reported delay is properly unset when it is no
|
||||
// longer present.
|
||||
state.HandleEchoPathChange(EchoPathVariability(
|
||||
false, EchoPathVariability::DelayAdjustment::kNone, false));
|
||||
state.Update(frequency_response, impulse_response, true, rtc::nullopt,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x, s,
|
||||
false);
|
||||
EXPECT_FALSE(state.ExternalDelay());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -182,9 +182,8 @@ void BlockProcessorImpl::ProcessCapture(
|
||||
|
||||
// Remove the echo from the capture signal.
|
||||
echo_remover_->ProcessCapture(
|
||||
delay_controller_->AlignmentHeadroomSamples(), echo_path_variability,
|
||||
capture_signal_saturation, render_buffer_->GetRenderBuffer(),
|
||||
capture_block);
|
||||
echo_path_variability, capture_signal_saturation,
|
||||
render_buffer_->GetRenderBuffer(), capture_block);
|
||||
|
||||
// Update the metrics.
|
||||
metrics_.UpdateCapture(false);
|
||||
|
@ -167,9 +167,7 @@ TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
|
||||
EXPECT_CALL(*render_delay_controller_mock, GetDelay(_, _))
|
||||
.Times(kNumBlocks)
|
||||
.WillRepeatedly(Return(9));
|
||||
EXPECT_CALL(*render_delay_controller_mock, AlignmentHeadroomSamples())
|
||||
.Times(kNumBlocks);
|
||||
EXPECT_CALL(*echo_remover_mock, ProcessCapture(_, _, _, _, _))
|
||||
EXPECT_CALL(*echo_remover_mock, ProcessCapture(_, _, _, _))
|
||||
.Times(kNumBlocks);
|
||||
EXPECT_CALL(*echo_remover_mock, UpdateEchoLeakageStatus(_))
|
||||
.Times(kNumBlocks);
|
||||
|
@ -58,8 +58,7 @@ class EchoRemoverImpl final : public EchoRemover {
|
||||
// Removes the echo from a block of samples from the capture signal. The
|
||||
// supplied render signal is assumed to be pre-aligned with the capture
|
||||
// signal.
|
||||
void ProcessCapture(const rtc::Optional<size_t>& echo_path_delay_samples,
|
||||
const EchoPathVariability& echo_path_variability,
|
||||
void ProcessCapture(const EchoPathVariability& echo_path_variability,
|
||||
bool capture_signal_saturation,
|
||||
RenderBuffer* render_buffer,
|
||||
std::vector<std::vector<float>>* capture) override;
|
||||
@ -120,7 +119,6 @@ void EchoRemoverImpl::GetMetrics(EchoControl::Metrics* metrics) const {
|
||||
}
|
||||
|
||||
void EchoRemoverImpl::ProcessCapture(
|
||||
const rtc::Optional<size_t>& echo_path_delay_samples,
|
||||
const EchoPathVariability& echo_path_variability,
|
||||
bool capture_signal_saturation,
|
||||
RenderBuffer* render_buffer,
|
||||
@ -179,9 +177,8 @@ void EchoRemoverImpl::ProcessCapture(
|
||||
// Update the AEC state information.
|
||||
aec_state_.Update(subtractor_.FilterFrequencyResponse(),
|
||||
subtractor_.FilterImpulseResponse(),
|
||||
subtractor_.ConvergedFilter(), echo_path_delay_samples,
|
||||
*render_buffer, E2_main, Y2, x0, subtractor_output.s_main,
|
||||
echo_leakage_detected_);
|
||||
subtractor_.ConvergedFilter(), *render_buffer, E2_main, Y2,
|
||||
x0, subtractor_output.s_main, echo_leakage_detected_);
|
||||
|
||||
// Choose the linear output.
|
||||
output_selector_.FormLinearOutput(!aec_state_.TransparentMode(), e_main, y0);
|
||||
@ -238,9 +235,6 @@ void EchoRemoverImpl::ProcessCapture(
|
||||
data_dumper_->DumpRaw(
|
||||
"aec3_filter_delay",
|
||||
aec_state_.FilterDelay() ? *aec_state_.FilterDelay() : -1);
|
||||
data_dumper_->DumpRaw(
|
||||
"aec3_external_delay",
|
||||
aec_state_.ExternalDelay() ? *aec_state_.ExternalDelay() : -1);
|
||||
data_dumper_->DumpRaw("aec3_capture_saturation",
|
||||
aec_state_.SaturatedCapture() ? 1 : 0);
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ class EchoRemover {
|
||||
// supplied render signal is assumed to be pre-aligned with the capture
|
||||
// signal.
|
||||
virtual void ProcessCapture(
|
||||
const rtc::Optional<size_t>& echo_path_delay_samples,
|
||||
const EchoPathVariability& echo_path_variability,
|
||||
bool capture_signal_saturation,
|
||||
RenderBuffer* render_buffer,
|
||||
|
@ -60,14 +60,10 @@ TEST(EchoRemover, BasicApiCalls) {
|
||||
k % 5 == 0 ? EchoPathVariability::DelayAdjustment::kNewDetectedDelay
|
||||
: EchoPathVariability::DelayAdjustment::kNone,
|
||||
false);
|
||||
rtc::Optional<size_t> echo_path_delay_samples =
|
||||
(k % 6 == 0 ? rtc::Optional<size_t>(k * 10)
|
||||
: rtc::nullopt);
|
||||
render_buffer->Insert(render);
|
||||
render_buffer->PrepareCaptureProcessing();
|
||||
|
||||
remover->ProcessCapture(echo_path_delay_samples, echo_path_variability,
|
||||
k % 2 == 0 ? true : false,
|
||||
remover->ProcessCapture(echo_path_variability, k % 2 == 0 ? true : false,
|
||||
render_buffer->GetRenderBuffer(), &capture);
|
||||
}
|
||||
}
|
||||
@ -96,11 +92,10 @@ TEST(EchoRemover, WrongCaptureBlockSize) {
|
||||
NumBandsForRate(rate), std::vector<float>(kBlockSize - 1, 0.f));
|
||||
EchoPathVariability echo_path_variability(
|
||||
false, EchoPathVariability::DelayAdjustment::kNone, false);
|
||||
rtc::Optional<size_t> echo_path_delay_samples;
|
||||
EXPECT_DEATH(remover->ProcessCapture(
|
||||
echo_path_delay_samples, echo_path_variability, false,
|
||||
render_buffer->GetRenderBuffer(), &capture),
|
||||
"");
|
||||
EXPECT_DEATH(
|
||||
remover->ProcessCapture(echo_path_variability, false,
|
||||
render_buffer->GetRenderBuffer(), &capture),
|
||||
"");
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,11 +114,10 @@ TEST(EchoRemover, DISABLED_WrongCaptureNumBands) {
|
||||
std::vector<float>(kBlockSize, 0.f));
|
||||
EchoPathVariability echo_path_variability(
|
||||
false, EchoPathVariability::DelayAdjustment::kNone, false);
|
||||
rtc::Optional<size_t> echo_path_delay_samples;
|
||||
EXPECT_DEATH(remover->ProcessCapture(
|
||||
echo_path_delay_samples, echo_path_variability, false,
|
||||
render_buffer->GetRenderBuffer(), &capture),
|
||||
"");
|
||||
EXPECT_DEATH(
|
||||
remover->ProcessCapture(echo_path_variability, false,
|
||||
render_buffer->GetRenderBuffer(), &capture),
|
||||
"");
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,10 +129,9 @@ TEST(EchoRemover, NullCapture) {
|
||||
RenderDelayBuffer::Create(EchoCanceller3Config(), 3));
|
||||
EchoPathVariability echo_path_variability(
|
||||
false, EchoPathVariability::DelayAdjustment::kNone, false);
|
||||
rtc::Optional<size_t> echo_path_delay_samples;
|
||||
EXPECT_DEATH(
|
||||
remover->ProcessCapture(echo_path_delay_samples, echo_path_variability,
|
||||
false, render_buffer->GetRenderBuffer(), nullptr),
|
||||
remover->ProcessCapture(echo_path_variability, false,
|
||||
render_buffer->GetRenderBuffer(), nullptr),
|
||||
"");
|
||||
}
|
||||
|
||||
@ -194,7 +187,7 @@ TEST(EchoRemover, BasicEchoRemoval) {
|
||||
render_buffer->Insert(x);
|
||||
render_buffer->PrepareCaptureProcessing();
|
||||
|
||||
remover->ProcessCapture(delay_samples, echo_path_variability, false,
|
||||
remover->ProcessCapture(echo_path_variability, false,
|
||||
render_buffer->GetRenderBuffer(), &y);
|
||||
|
||||
if (k > kNumBlocksToProcess / 2) {
|
||||
|
@ -157,7 +157,7 @@ void RunFilterUpdateTest(int num_blocks_to_process,
|
||||
aec_state.HandleEchoPathChange(EchoPathVariability(
|
||||
false, EchoPathVariability::DelayAdjustment::kNone, false));
|
||||
aec_state.Update(main_filter.FilterFrequencyResponse(),
|
||||
main_filter.FilterImpulseResponse(), true, rtc::nullopt,
|
||||
main_filter.FilterImpulseResponse(), true,
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0],
|
||||
s, false);
|
||||
}
|
||||
|
@ -26,9 +26,8 @@ class MockEchoRemover : public EchoRemover {
|
||||
public:
|
||||
virtual ~MockEchoRemover() = default;
|
||||
|
||||
MOCK_METHOD5(ProcessCapture,
|
||||
void(const rtc::Optional<size_t>& echo_path_delay_samples,
|
||||
const EchoPathVariability& echo_path_variability,
|
||||
MOCK_METHOD4(ProcessCapture,
|
||||
void(const EchoPathVariability& echo_path_variability,
|
||||
bool capture_signal_saturation,
|
||||
RenderBuffer* render_buffer,
|
||||
std::vector<std::vector<float>>* capture));
|
||||
|
@ -30,7 +30,6 @@ class MockRenderDelayController : public RenderDelayController {
|
||||
GetDelay,
|
||||
rtc::Optional<size_t>(const DownsampledRenderBuffer& render_buffer,
|
||||
rtc::ArrayView<const float> capture));
|
||||
MOCK_CONST_METHOD0(AlignmentHeadroomSamples, rtc::Optional<size_t>());
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
@ -35,9 +35,6 @@ class RenderDelayControllerImpl final : public RenderDelayController {
|
||||
void SetDelay(size_t render_delay) override;
|
||||
rtc::Optional<size_t> GetDelay(const DownsampledRenderBuffer& render_buffer,
|
||||
rtc::ArrayView<const float> capture) override;
|
||||
rtc::Optional<size_t> AlignmentHeadroomSamples() const override {
|
||||
return headroom_samples_;
|
||||
}
|
||||
|
||||
private:
|
||||
static int instance_count_;
|
||||
@ -45,7 +42,6 @@ class RenderDelayControllerImpl final : public RenderDelayController {
|
||||
rtc::Optional<size_t> delay_;
|
||||
EchoPathDelayEstimator delay_estimator_;
|
||||
size_t align_call_counter_ = 0;
|
||||
rtc::Optional<size_t> headroom_samples_;
|
||||
std::vector<float> delay_buf_;
|
||||
int delay_buf_index_ = 0;
|
||||
RenderDelayControllerMetrics metrics_;
|
||||
@ -91,7 +87,6 @@ RenderDelayControllerImpl::~RenderDelayControllerImpl() = default;
|
||||
void RenderDelayControllerImpl::Reset() {
|
||||
delay_ = rtc::nullopt;
|
||||
align_call_counter_ = 0;
|
||||
headroom_samples_ = rtc::nullopt;
|
||||
std::fill(delay_buf_.begin(), delay_buf_.end(), 0.f);
|
||||
delay_estimator_.Reset();
|
||||
}
|
||||
@ -126,11 +121,6 @@ rtc::Optional<size_t> RenderDelayControllerImpl::GetDelay(
|
||||
// Compute and set new render delay buffer delay.
|
||||
if (align_call_counter_ > kNumBlocksPerSecond) {
|
||||
delay_ = ComputeNewBufferDelay(delay_, static_cast<int>(*delay_samples));
|
||||
// Update render delay buffer headroom.
|
||||
const int headroom =
|
||||
static_cast<int>(*delay_samples) - *delay_ * kBlockSize;
|
||||
RTC_DCHECK_LE(0, headroom);
|
||||
headroom_samples_ = headroom;
|
||||
}
|
||||
|
||||
metrics_.Update(static_cast<int>(*delay_samples), delay_ ? *delay_ : 0);
|
||||
|
@ -38,9 +38,6 @@ class RenderDelayController {
|
||||
virtual rtc::Optional<size_t> GetDelay(
|
||||
const DownsampledRenderBuffer& render_buffer,
|
||||
rtc::ArrayView<const float> capture) = 0;
|
||||
|
||||
// Returns an approximate value for the headroom in the buffer alignment.
|
||||
virtual rtc::Optional<size_t> AlignmentHeadroomSamples() const = 0;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
|
@ -97,7 +97,6 @@ TEST(RenderDelayController, BasicApiCalls) {
|
||||
render_delay_buffer->GetDownsampledRenderBuffer(), capture_block);
|
||||
}
|
||||
EXPECT_TRUE(delay_blocks);
|
||||
EXPECT_FALSE(delay_controller->AlignmentHeadroomSamples());
|
||||
EXPECT_EQ(config.delay.min_echo_path_delay_blocks, delay_blocks);
|
||||
}
|
||||
}
|
||||
@ -147,12 +146,6 @@ TEST(RenderDelayController, Alignment) {
|
||||
kDelayHeadroomBlocks);
|
||||
|
||||
EXPECT_EQ(expected_delay_blocks, delay_blocks);
|
||||
|
||||
const rtc::Optional<size_t> headroom_samples =
|
||||
delay_controller->AlignmentHeadroomSamples();
|
||||
ASSERT_TRUE(headroom_samples);
|
||||
EXPECT_NEAR(delay_samples - *delay_blocks * kBlockSize,
|
||||
*headroom_samples, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -197,10 +190,6 @@ TEST(RenderDelayController, NonCausalAlignment) {
|
||||
}
|
||||
|
||||
ASSERT_FALSE(delay_blocks);
|
||||
|
||||
const rtc::Optional<size_t> headroom_samples =
|
||||
delay_controller->AlignmentHeadroomSamples();
|
||||
ASSERT_FALSE(headroom_samples);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -262,12 +251,6 @@ TEST(RenderDelayController, AlignmentWithJitter) {
|
||||
|
||||
ASSERT_TRUE(delay_blocks);
|
||||
EXPECT_EQ(expected_delay_blocks, *delay_blocks);
|
||||
|
||||
const rtc::Optional<size_t> headroom_samples =
|
||||
delay_controller->AlignmentHeadroomSamples();
|
||||
ASSERT_TRUE(headroom_samples);
|
||||
EXPECT_NEAR(delay_samples - *delay_blocks * kBlockSize,
|
||||
*headroom_samples, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,7 +275,6 @@ TEST(RenderDelayController, InitialHeadroom) {
|
||||
std::unique_ptr<RenderDelayController> delay_controller(
|
||||
RenderDelayController::Create(
|
||||
config, RenderDelayBuffer::DelayEstimatorOffset(config), rate));
|
||||
EXPECT_FALSE(delay_controller->AlignmentHeadroomSamples());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,17 +108,10 @@ void ResidualEchoEstimator::Estimate(
|
||||
R2->fill((*std::max_element(R2->begin(), R2->end())) * 100.f);
|
||||
}
|
||||
} else {
|
||||
const rtc::Optional<size_t> delay =
|
||||
aec_state.ExternalDelay()
|
||||
? (aec_state.FilterDelay() ? aec_state.FilterDelay()
|
||||
: aec_state.ExternalDelay())
|
||||
: rtc::Optional<size_t>();
|
||||
|
||||
// Estimate the echo generating signal power.
|
||||
std::array<float, kFftLengthBy2Plus1> X2;
|
||||
if (aec_state.ExternalDelay() && aec_state.FilterDelay()) {
|
||||
RTC_DCHECK(delay);
|
||||
const int delay_use = static_cast<int>(*delay);
|
||||
if (aec_state.FilterDelay()) {
|
||||
const int delay_use = static_cast<int>(*aec_state.FilterDelay());
|
||||
|
||||
// Computes the spectral power over the blocks surrounding the delay.
|
||||
constexpr int kKnownDelayRenderWindowSize = 5;
|
||||
@ -147,12 +140,9 @@ void ResidualEchoEstimator::Estimate(
|
||||
config_.ep_strength.bounded_erl,
|
||||
aec_state.TransparentMode(), X2, Y2, R2);
|
||||
|
||||
if (aec_state.ExternalDelay() && aec_state.FilterDelay() &&
|
||||
aec_state.SaturatedEcho()) {
|
||||
if (aec_state.FilterDelay() && aec_state.SaturatedEcho()) {
|
||||
AddEchoReverb(*R2, aec_state.SaturatedEcho(),
|
||||
std::min(static_cast<size_t>(config_.filter.length_blocks),
|
||||
delay.value_or(config_.filter.length_blocks)),
|
||||
aec_state.ReverbDecay(), R2);
|
||||
config_.filter.length_blocks, aec_state.ReverbDecay(), R2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ TEST(ResidualEchoEstimator, DISABLED_BasicTest) {
|
||||
render_delay_buffer->PrepareCaptureProcessing();
|
||||
|
||||
aec_state.HandleEchoPathChange(echo_path_variability);
|
||||
aec_state.Update(H2, h, true, 2, *render_delay_buffer->GetRenderBuffer(),
|
||||
aec_state.Update(H2, h, true, *render_delay_buffer->GetRenderBuffer(),
|
||||
E2_main, Y2, x[0], s, false);
|
||||
|
||||
estimator.Estimate(aec_state, *render_delay_buffer->GetRenderBuffer(),
|
||||
|
@ -84,7 +84,6 @@ float RunSubtractorTest(int num_blocks_to_process,
|
||||
aec_state.Update(subtractor.FilterFrequencyResponse(),
|
||||
subtractor.FilterImpulseResponse(),
|
||||
subtractor.ConvergedFilter(),
|
||||
rtc::Optional<size_t>(delay_samples / kBlockSize),
|
||||
*render_delay_buffer->GetRenderBuffer(), E2_main, Y2, x[0],
|
||||
output.s_main, false);
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||
s.fill(10.f);
|
||||
aec_state.Update(
|
||||
subtractor.FilterFrequencyResponse(), subtractor.FilterImpulseResponse(),
|
||||
subtractor.ConvergedFilter(), 10, *render_delay_buffer->GetRenderBuffer(),
|
||||
E2, Y2, x[0], s, false);
|
||||
subtractor.ConvergedFilter(), *render_delay_buffer->GetRenderBuffer(), E2,
|
||||
Y2, x[0], s, false);
|
||||
suppression_gain.GetGain(E2, R2, N2, analyzer, aec_state, x, &high_bands_gain,
|
||||
&g);
|
||||
std::for_each(g.begin(), g.end(), [](float a) { EXPECT_FLOAT_EQ(0.f, a); });
|
||||
@ -87,14 +87,14 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||
for (int k = 0; k <= kNumBlocksPerSecond / 5 + 1; ++k) {
|
||||
aec_state.Update(
|
||||
subtractor.FilterFrequencyResponse(),
|
||||
subtractor.FilterImpulseResponse(), subtractor.ConvergedFilter(), 10,
|
||||
subtractor.FilterImpulseResponse(), subtractor.ConvergedFilter(),
|
||||
*render_delay_buffer->GetRenderBuffer(), E2, Y2, x[0], s, false);
|
||||
}
|
||||
|
||||
for (int k = 0; k < 100; ++k) {
|
||||
aec_state.Update(
|
||||
subtractor.FilterFrequencyResponse(),
|
||||
subtractor.FilterImpulseResponse(), subtractor.ConvergedFilter(), 10,
|
||||
subtractor.FilterImpulseResponse(), subtractor.ConvergedFilter(),
|
||||
*render_delay_buffer->GetRenderBuffer(), E2, Y2, x[0], s, false);
|
||||
suppression_gain.GetGain(E2, R2, N2, analyzer, aec_state, x,
|
||||
&high_bands_gain, &g);
|
||||
@ -110,7 +110,7 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||
for (int k = 0; k < 100; ++k) {
|
||||
aec_state.Update(
|
||||
subtractor.FilterFrequencyResponse(),
|
||||
subtractor.FilterImpulseResponse(), subtractor.ConvergedFilter(), 10,
|
||||
subtractor.FilterImpulseResponse(), subtractor.ConvergedFilter(),
|
||||
*render_delay_buffer->GetRenderBuffer(), E2, Y2, x[0], s, false);
|
||||
suppression_gain.GetGain(E2, R2, N2, analyzer, aec_state, x,
|
||||
&high_bands_gain, &g);
|
||||
|
Reference in New Issue
Block a user