Add support to audioproc_f for running the residual echo detector and producing an echo likelihood graph.
This adds two command-line flags to audioproc_f: -red and -red_graph, which can be used to enable/disable the RED, and to set the output path for the graph. The graph is generated as a python script that depends on matplotlib and numpy to display the graph. BUG=webrtc:6525 Review-Url: https://codereview.webrtc.org/2486763002 Cr-Commit-Position: refs/heads/master@{#15069}
This commit is contained in:
parent
a013a02e01
commit
87d1a78754
@ -1496,6 +1496,8 @@ AudioProcessing::AudioProcessingStatistics AudioProcessingImpl::GetStatistics()
|
||||
metrics.echo_return_loss_enhancement);
|
||||
stats.residual_echo_return_loss.Set(metrics.residual_echo_return_loss);
|
||||
}
|
||||
stats.residual_echo_likelihood =
|
||||
private_submodules_->residual_echo_detector->echo_likelihood();
|
||||
public_submodules_->echo_cancellation->GetDelayMetrics(
|
||||
&stats.delay_median, &stats.delay_standard_deviation,
|
||||
&stats.fraction_poor_delays);
|
||||
|
||||
@ -450,6 +450,10 @@ void AecDumpBasedSimulator::HandleMessage(
|
||||
apm_config.level_controller.enabled = *settings_.use_lc;
|
||||
}
|
||||
|
||||
if (settings_.use_red) {
|
||||
apm_config.residual_echo_detector.enabled = *settings_.use_red;
|
||||
}
|
||||
|
||||
ap_->ApplyConfig(apm_config);
|
||||
ap_->SetExtraOptions(config);
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/stringutils.h"
|
||||
#include "webrtc/common_audio/include/audio_util.h"
|
||||
#include "webrtc/modules/audio_processing/include/audio_processing.h"
|
||||
@ -42,6 +43,22 @@ std::string GetIndexedOutputWavFilename(const std::string& wav_name,
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void WriteEchoLikelihoodGraphFileHeader(std::ofstream* output_file) {
|
||||
(*output_file) << "import numpy as np" << std::endl
|
||||
<< "import matplotlib.pyplot as plt" << std::endl
|
||||
<< "y = np.array([";
|
||||
}
|
||||
|
||||
void WriteEchoLikelihoodGraphFileFooter(std::ofstream* output_file) {
|
||||
(*output_file) << "])" << std::endl
|
||||
<< "x = np.arange(len(y))*.01" << std::endl
|
||||
<< "plt.plot(x, y)" << std::endl
|
||||
<< "plt.ylabel('Echo likelihood')" << std::endl
|
||||
<< "plt.xlabel('Time (s)')" << std::endl
|
||||
<< "plt.ylim([0,1])" << std::endl
|
||||
<< "plt.show()" << std::endl;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SimulationSettings::SimulationSettings() = default;
|
||||
@ -61,9 +78,22 @@ void CopyToAudioFrame(const ChannelBuffer<float>& src, AudioFrame* dest) {
|
||||
|
||||
AudioProcessingSimulator::AudioProcessingSimulator(
|
||||
const SimulationSettings& settings)
|
||||
: settings_(settings) {}
|
||||
: settings_(settings) {
|
||||
if (settings_.red_graph_output_filename &&
|
||||
settings_.red_graph_output_filename->size() > 0) {
|
||||
residual_echo_likelihood_graph_writer_.open(
|
||||
*settings_.red_graph_output_filename);
|
||||
RTC_CHECK(residual_echo_likelihood_graph_writer_.is_open());
|
||||
WriteEchoLikelihoodGraphFileHeader(&residual_echo_likelihood_graph_writer_);
|
||||
}
|
||||
}
|
||||
|
||||
AudioProcessingSimulator::~AudioProcessingSimulator() = default;
|
||||
AudioProcessingSimulator::~AudioProcessingSimulator() {
|
||||
if (residual_echo_likelihood_graph_writer_.is_open()) {
|
||||
WriteEchoLikelihoodGraphFileFooter(&residual_echo_likelihood_graph_writer_);
|
||||
residual_echo_likelihood_graph_writer_.close();
|
||||
}
|
||||
}
|
||||
|
||||
AudioProcessingSimulator::ScopedTimer::~ScopedTimer() {
|
||||
int64_t interval = rtc::TimeNanos() - start_time_;
|
||||
@ -90,6 +120,12 @@ void AudioProcessingSimulator::ProcessStream(bool fixed_interface) {
|
||||
buffer_writer_->Write(*out_buf_);
|
||||
}
|
||||
|
||||
if (residual_echo_likelihood_graph_writer_.is_open()) {
|
||||
auto stats = ap_->GetStatistics();
|
||||
residual_echo_likelihood_graph_writer_ << stats.residual_echo_likelihood
|
||||
<< ", ";
|
||||
}
|
||||
|
||||
++num_process_stream_calls_;
|
||||
}
|
||||
|
||||
@ -245,6 +281,9 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
|
||||
!settings_.use_extended_filter || *settings_.use_extended_filter));
|
||||
config.Set<DelayAgnostic>(new DelayAgnostic(!settings_.use_delay_agnostic ||
|
||||
*settings_.use_delay_agnostic));
|
||||
if (settings_.use_red) {
|
||||
apm_config.residual_echo_detector.enabled = *settings_.use_red;
|
||||
}
|
||||
|
||||
ap_.reset(AudioProcessing::Create(config));
|
||||
RTC_CHECK(ap_);
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_SIMULATOR_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -45,6 +46,8 @@ struct SimulationSettings {
|
||||
rtc::Optional<std::string> reverse_input_filename;
|
||||
rtc::Optional<bool> use_aec;
|
||||
rtc::Optional<bool> use_aecm;
|
||||
rtc::Optional<bool> use_red; // Residual Echo Detector.
|
||||
rtc::Optional<std::string> red_graph_output_filename;
|
||||
rtc::Optional<bool> use_agc;
|
||||
rtc::Optional<bool> use_hpf;
|
||||
rtc::Optional<bool> use_ns;
|
||||
@ -168,6 +171,7 @@ class AudioProcessingSimulator {
|
||||
std::unique_ptr<ChannelBufferWavWriter> buffer_writer_;
|
||||
std::unique_ptr<ChannelBufferWavWriter> reverse_buffer_writer_;
|
||||
TickIntervalStats proc_time_;
|
||||
std::ofstream residual_echo_likelihood_graph_writer_;
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioProcessingSimulator);
|
||||
};
|
||||
|
||||
@ -70,6 +70,10 @@ DEFINE_int32(aec,
|
||||
DEFINE_int32(aecm,
|
||||
kParameterNotSpecifiedValue,
|
||||
"Activate (1) or deactivate(0) the mobile echo controller");
|
||||
DEFINE_int32(red,
|
||||
kParameterNotSpecifiedValue,
|
||||
"Activate (1) or deactivate (0) the residual echo detector");
|
||||
DEFINE_string(red_graph, "", "Output filename for graph of echo likelihood");
|
||||
DEFINE_int32(agc,
|
||||
kParameterNotSpecifiedValue,
|
||||
"Activate (1) or deactivate(0) the AGC");
|
||||
@ -196,6 +200,7 @@ SimulationSettings CreateSettings() {
|
||||
settings.use_agc = rtc::Optional<bool>(true);
|
||||
settings.use_aec = rtc::Optional<bool>(true);
|
||||
settings.use_aecm = rtc::Optional<bool>(false);
|
||||
settings.use_red = rtc::Optional<bool>(false);
|
||||
}
|
||||
SetSettingIfSpecified(FLAGS_dump_input, &settings.aec_dump_input_filename);
|
||||
SetSettingIfSpecified(FLAGS_dump_output, &settings.aec_dump_output_filename);
|
||||
@ -215,6 +220,8 @@ SimulationSettings CreateSettings() {
|
||||
settings.target_angle_degrees = FLAGS_target_angle_degrees;
|
||||
SetSettingIfFlagSet(FLAGS_aec, &settings.use_aec);
|
||||
SetSettingIfFlagSet(FLAGS_aecm, &settings.use_aecm);
|
||||
SetSettingIfFlagSet(FLAGS_red, &settings.use_red);
|
||||
SetSettingIfSpecified(FLAGS_red_graph, &settings.red_graph_output_filename);
|
||||
SetSettingIfFlagSet(FLAGS_agc, &settings.use_agc);
|
||||
SetSettingIfFlagSet(FLAGS_hpf, &settings.use_hpf);
|
||||
SetSettingIfFlagSet(FLAGS_ns, &settings.use_ns);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user