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:
ivoc 2016-11-14 07:55:03 -08:00 committed by Commit bot
parent a013a02e01
commit 87d1a78754
5 changed files with 58 additions and 2 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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_);

View File

@ -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);
};

View File

@ -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);