Extend the audioproc_f input parameters to match what is supported by AEC3

This CL extends the options for the audioproc_f tool to match the options
for AEC3.

Bug: webrtc:8671
Change-Id: I39972eae33dba461b94118ec47a8560eb9cfe5a6
Reviewed-on: https://webrtc-review.googlesource.com/43120
Reviewed-by: Jesus de Vicente Pena <devicentepena@webrtc.org>
Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org>
Commit-Queue: Per Åhgren <peah@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22344}
This commit is contained in:
Per Åhgren 2018-03-08 07:47:14 +01:00 committed by Commit Bot
parent a51bbd8701
commit ad09d74f67
4 changed files with 230 additions and 1 deletions

View File

@ -716,6 +716,7 @@ if (rtc_include_tests) {
"../../rtc_base:checks",
"../../rtc_base:protobuf_utils",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:rtc_json",
"../../rtc_base:rtc_task_queue",
"../../rtc_base:stringutils",
"../../system_wrappers",

View File

@ -11,6 +11,7 @@
#include "modules/audio_processing/test/audio_processing_simulator.h"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
@ -23,6 +24,7 @@
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/test/fake_recording_device.h"
#include "rtc_base/checks.h"
#include "rtc_base/json.h"
#include "rtc_base/logging.h"
#include "rtc_base/stringutils.h"
@ -30,6 +32,223 @@ namespace webrtc {
namespace test {
namespace {
void ReadParam(const Json::Value& root, std::string param_name, bool* param) {
RTC_CHECK(param);
bool v;
if (rtc::GetBoolFromJsonObject(root, param_name, &v)) {
*param = v;
std::cout << param_name << ":" << (*param ? "true" : "false") << std::endl;
}
}
void ReadParam(const Json::Value& root, std::string param_name, size_t* param) {
RTC_CHECK(param);
int v;
if (rtc::GetIntFromJsonObject(root, param_name, &v)) {
*param = v;
std::cout << param_name << ":" << *param << std::endl;
}
}
void ReadParam(const Json::Value& root, std::string param_name, int* param) {
RTC_CHECK(param);
int v;
if (rtc::GetIntFromJsonObject(root, param_name, &v)) {
*param = v;
std::cout << param_name << ":" << *param << std::endl;
}
}
void ReadParam(const Json::Value& root, std::string param_name, float* param) {
RTC_CHECK(param);
double v;
if (rtc::GetDoubleFromJsonObject(root, param_name, &v)) {
*param = static_cast<float>(v);
std::cout << param_name << ":" << *param << std::endl;
}
}
void ReadParam(const Json::Value& root,
std::string param_name,
EchoCanceller3Config::Filter::MainConfiguration* param) {
RTC_CHECK(param);
Json::Value json_array;
if (rtc::GetValueFromJsonObject(root, param_name, &json_array)) {
std::vector<double> v;
rtc::JsonArrayToDoubleVector(json_array, &v);
if (v.size() != 5) {
std::cout << "Incorrect array size for " << param_name << std::endl;
RTC_CHECK(false);
}
param->length_blocks = static_cast<size_t>(v[0]);
param->leakage_converged = static_cast<float>(v[1]);
param->leakage_diverged = static_cast<float>(v[2]);
param->error_floor = static_cast<float>(v[3]);
param->noise_gate = static_cast<float>(v[4]);
std::cout << param_name << ":"
<< "[" << param->length_blocks << "," << param->leakage_converged
<< "," << param->leakage_diverged << "," << param->error_floor
<< "," << param->noise_gate << "]" << std::endl;
}
}
void ReadParam(const Json::Value& root,
std::string param_name,
EchoCanceller3Config::Filter::ShadowConfiguration* param) {
RTC_CHECK(param);
Json::Value json_array;
if (rtc::GetValueFromJsonObject(root, param_name, &json_array)) {
std::vector<double> v;
rtc::JsonArrayToDoubleVector(json_array, &v);
if (v.size() != 3) {
std::cout << "Incorrect array size for " << param_name << std::endl;
RTC_CHECK(false);
}
param->length_blocks = static_cast<size_t>(v[0]);
param->rate = static_cast<float>(v[1]);
param->noise_gate = static_cast<float>(v[2]);
std::cout << param_name << ":"
<< "[" << param->length_blocks << "," << param->rate << ","
<< param->noise_gate << "]" << std::endl;
}
}
void ReadParam(const Json::Value& root,
std::string param_name,
EchoCanceller3Config::GainUpdates::GainChanges* param) {
RTC_CHECK(param);
Json::Value json_array;
if (rtc::GetValueFromJsonObject(root, param_name, &json_array)) {
std::vector<double> v;
rtc::JsonArrayToDoubleVector(json_array, &v);
if (v.size() != 6) {
std::cout << "Incorrect array size for " << param_name << std::endl;
RTC_CHECK(false);
}
param->max_inc = static_cast<float>(v[0]);
param->max_dec = static_cast<float>(v[1]);
param->rate_inc = static_cast<float>(v[2]);
param->rate_dec = static_cast<float>(v[3]);
param->min_inc = static_cast<float>(v[4]);
param->min_dec = static_cast<float>(v[5]);
std::cout << param_name << ":"
<< "[" << param->max_inc << "," << param->max_dec << ","
<< param->rate_inc << "," << param->rate_dec << ","
<< param->min_inc << "," << param->min_dec << "]" << std::endl;
}
}
EchoCanceller3Config ParseAec3Parameters(const std::string& filename) {
EchoCanceller3Config cfg;
Json::Value root;
std::string s;
std::string json_string;
std::ifstream f(filename.c_str());
if (f.fail()) {
std::cout << "Failed to open the file " << filename << std::endl;
RTC_CHECK(false);
}
while (std::getline(f, s)) {
json_string += s;
}
bool failed = Json::Reader().parse(json_string, root);
if (failed) {
std::cout << "Incorrect JSON format:" << std::endl;
std::cout << json_string << std::endl;
RTC_CHECK(false);
}
std::cout << "AEC3 Parameters from JSON input:" << std::endl;
Json::Value section;
if (rtc::GetValueFromJsonObject(root, "delay", &section)) {
ReadParam(section, "default_delay", &cfg.delay.default_delay);
ReadParam(section, "down_sampling_factor", &cfg.delay.down_sampling_factor);
ReadParam(section, "num_filters", &cfg.delay.num_filters);
ReadParam(section, "api_call_jitter_blocks",
&cfg.delay.api_call_jitter_blocks);
ReadParam(section, "min_echo_path_delay_blocks",
&cfg.delay.min_echo_path_delay_blocks);
ReadParam(section, "delay_headroom_blocks",
&cfg.delay.delay_headroom_blocks);
ReadParam(section, "hysteresis_limit_1_blocks",
&cfg.delay.hysteresis_limit_1_blocks);
ReadParam(section, "hysteresis_limit_2_blocks",
&cfg.delay.hysteresis_limit_2_blocks);
}
if (rtc::GetValueFromJsonObject(root, "filter", &section)) {
ReadParam(section, "main", &cfg.filter.main);
ReadParam(section, "shadow", &cfg.filter.shadow);
ReadParam(section, "main_initial", &cfg.filter.main_initial);
ReadParam(section, "shadow_initial", &cfg.filter.shadow_initial);
}
if (rtc::GetValueFromJsonObject(root, "erle", &section)) {
ReadParam(section, "min", &cfg.erle.min);
ReadParam(section, "max_l", &cfg.erle.max_l);
ReadParam(section, "max_h", &cfg.erle.max_h);
}
if (rtc::GetValueFromJsonObject(root, "ep_strength", &section)) {
ReadParam(section, "lf", &cfg.ep_strength.lf);
ReadParam(section, "mf", &cfg.ep_strength.mf);
ReadParam(section, "hf", &cfg.ep_strength.hf);
ReadParam(section, "default_len", &cfg.ep_strength.default_len);
ReadParam(section, "echo_can_saturate", &cfg.ep_strength.echo_can_saturate);
ReadParam(section, "bounded_erl", &cfg.ep_strength.bounded_erl);
}
if (rtc::GetValueFromJsonObject(root, "gain_mask", &section)) {
ReadParam(section, "m1", &cfg.gain_mask.m1);
ReadParam(section, "m2", &cfg.gain_mask.m2);
ReadParam(section, "m3", &cfg.gain_mask.m3);
ReadParam(section, "m4", &cfg.gain_mask.m4);
ReadParam(section, "m5", &cfg.gain_mask.m5);
ReadParam(section, "m6", &cfg.gain_mask.m6);
ReadParam(section, "m7", &cfg.gain_mask.m7);
ReadParam(section, "m8", &cfg.gain_mask.m8);
ReadParam(section, "m9", &cfg.gain_mask.m9);
}
if (rtc::GetValueFromJsonObject(root, "echo_audibility", &section)) {
ReadParam(section, "low_render_limit",
&cfg.echo_audibility.low_render_limit);
ReadParam(section, "normal_render_limit",
&cfg.echo_audibility.normal_render_limit);
}
if (rtc::GetValueFromJsonObject(root, "gain_updates", &section)) {
ReadParam(section, "low_noise", &cfg.gain_updates.low_noise);
ReadParam(section, "initial", &cfg.gain_updates.initial);
ReadParam(section, "normal", &cfg.gain_updates.normal);
ReadParam(section, "saturation", &cfg.gain_updates.saturation);
ReadParam(section, "nonlinear", &cfg.gain_updates.nonlinear);
ReadParam(section, "floor_first_increase",
&cfg.gain_updates.floor_first_increase);
}
if (rtc::GetValueFromJsonObject(root, "echo_removal_control", &section)) {
Json::Value subsection;
if (rtc::GetValueFromJsonObject(section, "gain_rampup", &subsection)) {
ReadParam(section, "first_non_zero_gain",
&cfg.echo_removal_control.gain_rampup.first_non_zero_gain);
ReadParam(section, "non_zero_gain_blocks",
&cfg.echo_removal_control.gain_rampup.non_zero_gain_blocks);
ReadParam(section, "full_gain_blocks",
&cfg.echo_removal_control.gain_rampup.full_gain_blocks);
}
ReadParam(section, "has_clock_drift",
&cfg.echo_removal_control.has_clock_drift);
}
std::cout << std::endl;
return cfg;
}
void CopyFromAudioFrame(const AudioFrame& src, ChannelBuffer<float>* dest) {
RTC_CHECK_EQ(src.num_channels_, dest->num_channels());
RTC_CHECK_EQ(src.samples_per_channel_, dest->num_frames());
@ -326,7 +545,11 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
apm_config.gain_controller2.fixed_gain_db = settings_.agc2_fixed_gain_db;
}
if (settings_.use_aec3 && *settings_.use_aec3) {
echo_control_factory.reset(new EchoCanceller3Factory());
EchoCanceller3Config cfg;
if (settings_.aec3_settings_filename) {
cfg = ParseAec3Parameters(*settings_.aec3_settings_filename);
}
echo_control_factory.reset(new EchoCanceller3Factory(cfg));
}
if (settings_.use_lc) {
apm_config.level_controller.enabled = *settings_.use_lc;

View File

@ -90,6 +90,7 @@ struct SimulationSettings {
bool fixed_interface = false;
bool store_intermediate_output = false;
rtc::Optional<std::string> custom_call_order_filename;
rtc::Optional<std::string> aec3_settings_filename;
};
// Holds a few statistics about a series of TickIntervals.

View File

@ -181,6 +181,9 @@ DEFINE_bool(store_intermediate_output,
false,
"Creates new output files after each init");
DEFINE_string(custom_call_order_file, "", "Custom process API call order file");
DEFINE_string(aec3_settings,
"",
"File in JSON-format with custom AEC3 settings");
DEFINE_bool(help, false, "Print this message");
void SetSettingIfSpecified(const std::string& value,
@ -279,6 +282,7 @@ SimulationSettings CreateSettings() {
&settings.stream_drift_samples);
SetSettingIfSpecified(FLAG_custom_call_order_file,
&settings.custom_call_order_filename);
SetSettingIfSpecified(FLAG_aec3_settings, &settings.aec3_settings_filename);
settings.initial_mic_level = FLAG_initial_mic_level;
settings.simulate_mic_gain = FLAG_simulate_mic_gain;
SetSettingIfSpecified(FLAG_simulated_mic_kind, &settings.simulated_mic_kind);