APM reports ERL and ERLE metrics for AEC3.
The audio processing module reports the metrics 'echo return loss' and 'echo return loss enhancement' for AEC3. Bug: webrtc:8533 Change-Id: I166c504adf013d6cb5d6d3c9717d0622c3454bb7 Reviewed-on: https://webrtc-review.googlesource.com/24880 Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org> Reviewed-by: Ivo Creusen <ivoc@webrtc.org> Reviewed-by: Per Åhgren <peah@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20835}
This commit is contained in:
parent
63e232a2cf
commit
332150d7df
@ -50,11 +50,17 @@ class AecState {
|
||||
return erle_estimator_.Erle();
|
||||
}
|
||||
|
||||
// Returns the time-domain ERLE.
|
||||
float ErleTimeDomain() const { return erle_estimator_.ErleTimeDomain(); }
|
||||
|
||||
// Returns the ERL.
|
||||
const std::array<float, kFftLengthBy2Plus1>& Erl() const {
|
||||
return erl_estimator_.Erl();
|
||||
}
|
||||
|
||||
// Returns the time-domain ERL.
|
||||
float ErlTimeDomain() const { return erl_estimator_.ErlTimeDomain(); }
|
||||
|
||||
// Returns the delay estimate based on the linear filter.
|
||||
rtc::Optional<size_t> FilterDelay() const { return filter_delay_; }
|
||||
|
||||
|
||||
@ -40,6 +40,8 @@ class BlockProcessorImpl final : public BlockProcessor {
|
||||
|
||||
void UpdateEchoLeakageStatus(bool leakage_detected) override;
|
||||
|
||||
void GetMetrics(EchoControl::Metrics* metrics) const override;
|
||||
|
||||
private:
|
||||
static int instance_count_;
|
||||
bool no_capture_data_received_ = true;
|
||||
@ -179,6 +181,10 @@ void BlockProcessorImpl::UpdateEchoLeakageStatus(bool leakage_detected) {
|
||||
echo_remover_->UpdateEchoLeakageStatus(leakage_detected);
|
||||
}
|
||||
|
||||
void BlockProcessorImpl::GetMetrics(EchoControl::Metrics* metrics) const {
|
||||
echo_remover_->GetMetrics(metrics);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BlockProcessor* BlockProcessor::Create(const EchoCanceller3Config& config,
|
||||
|
||||
@ -39,6 +39,9 @@ class BlockProcessor {
|
||||
|
||||
virtual ~BlockProcessor() = default;
|
||||
|
||||
// Get current metrics.
|
||||
virtual void GetMetrics(EchoControl::Metrics* metrics) const = 0;
|
||||
|
||||
// Processes a block of capture data.
|
||||
virtual void ProcessCapture(
|
||||
bool echo_path_gain_change,
|
||||
|
||||
@ -323,6 +323,13 @@ void EchoCanceller3::ProcessCapture(AudioBuffer* capture, bool level_change) {
|
||||
LowestBandRate(sample_rate_hz_), 1);
|
||||
}
|
||||
|
||||
EchoControl::Metrics EchoCanceller3::GetMetrics() const {
|
||||
RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
|
||||
Metrics metrics;
|
||||
block_processor_->GetMetrics(&metrics);
|
||||
return metrics;
|
||||
}
|
||||
|
||||
bool EchoCanceller3::Validate(const EchoCanceller3Config& config) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -79,6 +79,8 @@ class EchoCanceller3 : public EchoControl {
|
||||
// Processes the split-band domain capture signal in order to remove any echo
|
||||
// present in the signal.
|
||||
void ProcessCapture(AudioBuffer* capture, bool level_change) override;
|
||||
// Collect current metrics from the echo canceller.
|
||||
Metrics GetMetrics() const override;
|
||||
|
||||
// Signals whether an external detector has detected echo leakage from the
|
||||
// echo canceller.
|
||||
|
||||
@ -102,6 +102,8 @@ class CaptureTransportVerificationProcessor : public BlockProcessor {
|
||||
|
||||
void UpdateEchoLeakageStatus(bool leakage_detected) override {}
|
||||
|
||||
void GetMetrics(EchoControl::Metrics* metrics) const override {}
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTransportVerificationProcessor);
|
||||
};
|
||||
@ -128,6 +130,8 @@ class RenderTransportVerificationProcessor : public BlockProcessor {
|
||||
|
||||
void UpdateEchoLeakageStatus(bool leakage_detected) override {}
|
||||
|
||||
void GetMetrics(EchoControl::Metrics* metrics) const override {}
|
||||
|
||||
private:
|
||||
std::deque<std::vector<std::vector<float>>> received_render_blocks_;
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderTransportVerificationProcessor);
|
||||
|
||||
@ -53,6 +53,8 @@ class EchoRemoverImpl final : public EchoRemover {
|
||||
int sample_rate_hz);
|
||||
~EchoRemoverImpl() override;
|
||||
|
||||
void GetMetrics(EchoControl::Metrics* metrics) const override;
|
||||
|
||||
// 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.
|
||||
@ -110,6 +112,13 @@ EchoRemoverImpl::EchoRemoverImpl(const EchoCanceller3Config& config,
|
||||
|
||||
EchoRemoverImpl::~EchoRemoverImpl() = default;
|
||||
|
||||
void EchoRemoverImpl::GetMetrics(EchoControl::Metrics* metrics) const {
|
||||
// Echo return loss (ERL) is inverted to go from gain to attenuation.
|
||||
metrics->echo_return_loss = -10.0 * log10(aec_state_.ErlTimeDomain());
|
||||
metrics->echo_return_loss_enhancement =
|
||||
10.0 * log10(aec_state_.ErleTimeDomain());
|
||||
}
|
||||
|
||||
void EchoRemoverImpl::ProcessCapture(
|
||||
const rtc::Optional<size_t>& echo_path_delay_samples,
|
||||
const EchoPathVariability& echo_path_variability,
|
||||
|
||||
@ -27,6 +27,9 @@ class EchoRemover {
|
||||
int sample_rate_hz);
|
||||
virtual ~EchoRemover() = default;
|
||||
|
||||
// Get current metrics.
|
||||
virtual void GetMetrics(EchoControl::Metrics* metrics) const = 0;
|
||||
|
||||
// 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.
|
||||
|
||||
@ -31,7 +31,7 @@ class ErleEstimator {
|
||||
|
||||
// Returns the most recent ERLE estimate.
|
||||
const std::array<float, kFftLengthBy2Plus1>& Erle() const { return erle_; }
|
||||
float ErleTimeDomain() { return erle_time_domain_; }
|
||||
float ErleTimeDomain() const { return erle_time_domain_; }
|
||||
|
||||
private:
|
||||
std::array<float, kFftLengthBy2Plus1> erle_;
|
||||
|
||||
@ -30,6 +30,7 @@ class MockBlockProcessor : public BlockProcessor {
|
||||
MOCK_METHOD1(BufferRender,
|
||||
void(const std::vector<std::vector<float>>& block));
|
||||
MOCK_METHOD1(UpdateEchoLeakageStatus, void(bool leakage_detected));
|
||||
MOCK_CONST_METHOD1(GetMetrics, void(EchoControl::Metrics* metrics));
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
||||
@ -34,6 +34,7 @@ class MockEchoRemover : public EchoRemover {
|
||||
std::vector<std::vector<float>>* capture));
|
||||
|
||||
MOCK_METHOD1(UpdateEchoLeakageStatus, void(bool leakage_detected));
|
||||
MOCK_CONST_METHOD1(GetMetrics, void(EchoControl::Metrics* metrics));
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
||||
@ -1608,8 +1608,16 @@ AudioProcessing::AudioProcessingStats AudioProcessingImpl::GetStatistics(
|
||||
AudioProcessingStats stats;
|
||||
if (has_remote_tracks) {
|
||||
EchoCancellation::Metrics metrics;
|
||||
if (public_submodules_->echo_cancellation->GetMetrics(&metrics) ==
|
||||
Error::kNoError) {
|
||||
if (private_submodules_->echo_controller) {
|
||||
rtc::CritScope cs_capture(&crit_capture_);
|
||||
EchoControl::Metrics ec_metrics =
|
||||
private_submodules_->echo_controller->GetMetrics();
|
||||
stats.echo_return_loss =
|
||||
rtc::Optional<double>(ec_metrics.echo_return_loss);
|
||||
stats.echo_return_loss_enhancement =
|
||||
rtc::Optional<double>(ec_metrics.echo_return_loss_enhancement);
|
||||
} else if (public_submodules_->echo_cancellation->GetMetrics(&metrics) ==
|
||||
Error::kNoError) {
|
||||
if (metrics.divergent_filter_fraction != -1.0f) {
|
||||
stats.divergent_filter_fraction =
|
||||
rtc::Optional<double>(metrics.divergent_filter_fraction);
|
||||
|
||||
@ -940,6 +940,14 @@ class EchoControl {
|
||||
// Processes the capture signal in order to remove the echo.
|
||||
virtual void ProcessCapture(AudioBuffer* capture, bool echo_path_change) = 0;
|
||||
|
||||
struct Metrics {
|
||||
double echo_return_loss;
|
||||
double echo_return_loss_enhancement;
|
||||
};
|
||||
|
||||
// Collect current metrics from the echo controller.
|
||||
virtual Metrics GetMetrics() const = 0;
|
||||
|
||||
virtual ~EchoControl() {}
|
||||
};
|
||||
|
||||
|
||||
@ -119,6 +119,7 @@ class MockEchoControl : public EchoControl {
|
||||
MOCK_METHOD1(AnalyzeCapture, void(AudioBuffer* capture));
|
||||
MOCK_METHOD2(ProcessCapture,
|
||||
void(AudioBuffer* capture, bool echo_path_change));
|
||||
MOCK_CONST_METHOD0(GetMetrics, Metrics());
|
||||
};
|
||||
|
||||
class MockVoiceDetection : public VoiceDetection {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user