use crate::common::FFT_LENGTH_BY_2_PLUS_1;
use crate::config::EchoCanceller3Config;
use crate::fullband_erle_estimator::FullBandErleEstimator;
use crate::render_buffer::RenderBuffer;
use crate::signal_dependent_erle_estimator::{ErleUpdateContext, SignalDependentErleEstimator};
use crate::subband_erle_estimator::SubbandErleEstimator;
#[derive(Debug)]
pub(crate) struct ErleEstimator {
startup_phase_length_blocks: usize,
fullband_erle_estimator: FullBandErleEstimator,
subband_erle_estimator: SubbandErleEstimator,
signal_dependent_erle_estimator: Option<SignalDependentErleEstimator>,
blocks_since_reset: usize,
}
impl ErleEstimator {
pub(crate) fn new(
startup_phase_length_blocks: usize,
config: &EchoCanceller3Config,
num_capture_channels: usize,
) -> Self {
let signal_dependent = if config.erle.num_sections > 1 {
Some(SignalDependentErleEstimator::new(
config,
num_capture_channels,
))
} else {
None
};
let mut s = Self {
startup_phase_length_blocks,
fullband_erle_estimator: FullBandErleEstimator::new(&config.erle, num_capture_channels),
subband_erle_estimator: SubbandErleEstimator::new(config, num_capture_channels),
signal_dependent_erle_estimator: signal_dependent,
blocks_since_reset: 0,
};
s.reset(true);
s
}
pub(crate) fn reset(&mut self, delay_change: bool) {
self.fullband_erle_estimator.reset();
self.subband_erle_estimator.reset();
if let Some(ref mut sd) = self.signal_dependent_erle_estimator {
sd.reset();
}
if delay_change {
self.blocks_since_reset = 0;
}
}
pub(crate) fn update(
&mut self,
render_buffer: &RenderBuffer<'_>,
filter_frequency_responses: &[Vec<[f32; FFT_LENGTH_BY_2_PLUS_1]>],
x2_reverb: &[f32; FFT_LENGTH_BY_2_PLUS_1],
y2: &[[f32; FFT_LENGTH_BY_2_PLUS_1]],
e2: &[[f32; FFT_LENGTH_BY_2_PLUS_1]],
converged_filters: &[bool],
) {
self.blocks_since_reset += 1;
if self.blocks_since_reset < self.startup_phase_length_blocks {
return;
}
self.subband_erle_estimator
.update(x2_reverb, y2, e2, converged_filters);
if let Some(ref mut sd) = self.signal_dependent_erle_estimator {
sd.update(&ErleUpdateContext {
render_buffer,
filter_frequency_responses,
x2: x2_reverb,
y2,
e2,
average_erle: self.subband_erle_estimator.erle(false),
average_erle_onset_compensated: self.subband_erle_estimator.erle(true),
converged_filters,
});
}
self.fullband_erle_estimator
.update(x2_reverb, y2, e2, converged_filters);
}
pub(crate) fn erle(&self, onset_compensated: bool) -> &[[f32; FFT_LENGTH_BY_2_PLUS_1]] {
if let Some(ref sd) = self.signal_dependent_erle_estimator {
sd.erle(onset_compensated)
} else {
self.subband_erle_estimator.erle(onset_compensated)
}
}
pub(crate) fn erle_unbounded(&self) -> &[[f32; FFT_LENGTH_BY_2_PLUS_1]] {
if let Some(ref est) = self.signal_dependent_erle_estimator {
est.erle(false)
} else {
self.subband_erle_estimator.erle_unbounded()
}
}
pub(crate) fn fullband_erle_log2(&self) -> f32 {
self.fullband_erle_estimator.fullband_erle_log2()
}
pub(crate) fn get_inst_linear_quality_estimates(&self) -> &[Option<f32>] {
self.fullband_erle_estimator
.get_inst_linear_quality_estimates()
}
}