Index: webrtc/modules/audio_processing/test/audioproc_float.cc |
diff --git a/webrtc/modules/audio_processing/test/audioproc_float.cc b/webrtc/modules/audio_processing/test/audioproc_float.cc |
index 41e45bfdc69c5c20525d89a0df3dc771fb70004d..b38b7b2052d28cecaa52f7ba8a385f1b8161ba59 100644 |
--- a/webrtc/modules/audio_processing/test/audioproc_float.cc |
+++ b/webrtc/modules/audio_processing/test/audioproc_float.cc |
@@ -8,179 +8,429 @@ |
* be found in the AUTHORS file in the root of the source tree. |
*/ |
-#include <stdio.h> |
- |
-#include <iostream> |
#include <memory> |
-#include <sstream> |
-#include <string> |
-#include <utility> |
#include "gflags/gflags.h" |
-#include "webrtc/base/checks.h" |
-#include "webrtc/base/format_macros.h" |
-#include "webrtc/common_audio/channel_buffer.h" |
-#include "webrtc/common_audio/wav_file.h" |
#include "webrtc/modules/audio_processing/include/audio_processing.h" |
-#include "webrtc/modules/audio_processing/test/audio_file_processor.h" |
-#include "webrtc/modules/audio_processing/test/protobuf_utils.h" |
-#include "webrtc/modules/audio_processing/test/test_utils.h" |
-#include "webrtc/system_wrappers/include/tick_util.h" |
-#include "webrtc/test/testsupport/trace_to_stderr.h" |
+#include "webrtc/modules/audio_processing/test/aec_dump_based_simulator.h" |
+#include "webrtc/modules/audio_processing/test/audio_processing_simulator.h" |
+#include "webrtc/modules/audio_processing/test/wav_based_simulator.h" |
+namespace webrtc { |
+namespace test { |
namespace { |
-bool ValidateOutChannels(const char* flagname, int32_t value) { |
- return value >= 0; |
+const int kParameterNotSpecifiedValue = -10000; |
+ |
+const char kUsageDescription[] = |
+ "Usage: audioproc_f [options] -i <input.wav>\n" |
+ " or\n" |
+ " audioproc_f [options] -dump <aec_dump>\n" |
+ "\n\n" |
+ "Command-line tool to simulate a call using the audio " |
+ "processing module, either based on wav files or " |
+ "protobuf debug dump recordings and writes to an output"; |
+ |
+DEFINE_string(dump_input, "", "Aec dump input filename"); |
+DEFINE_string(dump_output, "", "Aec dump output filename"); |
+DEFINE_string(i, "", "Forward stream input wav filename"); |
+DEFINE_string(o, "", "Forward stream output wav filename"); |
+DEFINE_string(ri, "", "Reverse stream input wav filename"); |
+DEFINE_string(ro, "", "Reverse stream output wav filename"); |
+DEFINE_int32(output_num_channels, |
+ kParameterNotSpecifiedValue, |
+ "Number of forward stream output channels"); |
+DEFINE_int32(reverse_output_num_channels, |
+ kParameterNotSpecifiedValue, |
+ "Number of Reverse stream output channels"); |
+DEFINE_int32(output_sample_rate_hz, |
+ kParameterNotSpecifiedValue, |
+ "Forward stream output sample rate in Hz"); |
+DEFINE_int32(reverse_output_sample_rate_hz, |
+ kParameterNotSpecifiedValue, |
+ "Reverse stream output sample rate in Hz"); |
+DEFINE_string(mic_positions, |
+ "", |
+ "Space delimited cartesian coordinates of microphones in " |
+ "meters. The coordinates of each point are contiguous. For a " |
+ "two element array: \"x1 y1 z1 x2 y2 z2\""); |
+DEFINE_int32(target_angle_degrees, |
+ 90, |
+ "The azimuth of the target in degrees (0-359). Only applies to " |
+ "beamforming."); |
+DEFINE_bool(fixed_interface, |
+ false, |
+ "Use the fixed interface when operating on wav files"); |
+DEFINE_bool(aec, false, "Activate the echo canceller"); |
+DEFINE_bool(no_aec, false, "Dectivate the echo canceller"); |
+DEFINE_bool(aecm, false, "Activate the mobile echo controller"); |
+DEFINE_bool(no_aecm, false, "Dectivate the mobile echo controller"); |
+DEFINE_bool(agc, false, "Activate the AGC"); |
+DEFINE_bool(no_agc, false, "Dectivate the AGC"); |
+DEFINE_bool(hpf, false, "Activate the high-pass filter"); |
+DEFINE_bool(no_hpf, false, "Dectivate the high-pass filter"); |
+DEFINE_bool(ns, false, "Activate the noise suppressor"); |
+DEFINE_bool(no_ns, false, "Dectivate the noise suppressor"); |
+DEFINE_bool(ts, false, "Activate the transient suppressor"); |
+DEFINE_bool(no_ts, false, "Dectivate the transient suppressor"); |
+DEFINE_bool(bf, false, "Activate the beamformer"); |
+DEFINE_bool(no_bf, false, "Dectivate the beamformer"); |
+DEFINE_bool(ie, false, "Activate the intelligibility enhancer"); |
+DEFINE_bool(no_ie, false, "Dectivate the intelligibility enhancer"); |
+DEFINE_bool(vad, false, "Activate the voice activity detector"); |
+DEFINE_bool(no_vad, false, "Dectivate the voice activity detector"); |
+DEFINE_bool(le, false, "Activate the level estimator"); |
+DEFINE_bool(no_le, false, "Dectivate the level estimator"); |
+DEFINE_bool(all_default, |
+ false, |
+ "Activate all of the default components (will be overridden by any " |
+ "other settings)"); |
+DEFINE_int32(aec_suppression_level, |
+ kParameterNotSpecifiedValue, |
+ "Set the aec suppression level (0-2)"); |
+DEFINE_bool(delay_agnostic, false, "Activate the level estimator"); |
+DEFINE_bool(no_delay_agnostic, false, "Dectivate the level estimator"); |
+DEFINE_bool(extended_filter, false, "Activate the level estimator"); |
+DEFINE_bool(no_extended_filter, false, "Dectivate the level estimator"); |
+DEFINE_bool(drift_compensation, false, "Activate the level estimator"); |
+DEFINE_bool(no_drift_compensation, false, "Dectivate the level estimator"); |
+DEFINE_bool(aec3, false, "Activate the level estimator"); |
+DEFINE_bool(no_aec3, false, "Dectivate the level estimator"); |
+DEFINE_bool(refined_adaptive_filter, |
+ false, |
+ "Activate the refined adaptive filter functionality"); |
+DEFINE_bool(no_refined_adaptive_filter, |
+ false, |
+ "Deactivate the refined adaptive filter functionality"); |
+DEFINE_int32(aecm_routing_mode, |
+ kParameterNotSpecifiedValue, |
+ "Specify the AECM routing mode (0-4)"); |
+DEFINE_bool(aecm_comfort_noise, false, "Activate the AECM comfort noise"); |
+DEFINE_bool(no_aecm_comfort_noise, false, "Dectivate the AECM comfort noise"); |
+DEFINE_int32(agc_mode, |
+ kParameterNotSpecifiedValue, |
+ "Specify the AGC mode (0-2)"); |
+DEFINE_int32(agc_target_level, |
+ kParameterNotSpecifiedValue, |
+ "Specify the AGC target level (0-31)"); |
+DEFINE_bool(agc_limiter, false, "Activate the level estimator"); |
+DEFINE_bool(no_agc_limiter, false, "Dectivate the level estimator"); |
+DEFINE_int32(agc_compression_gain, |
+ kParameterNotSpecifiedValue, |
+ "Specify the AGC compression gain (0-90)"); |
+DEFINE_int32(vad_likelihood, |
+ kParameterNotSpecifiedValue, |
+ "Specify the VAD likelihood (0-3)"); |
+DEFINE_int32(ns_level, |
+ kParameterNotSpecifiedValue, |
+ "Specify the NS level (0-3)"); |
+DEFINE_int32(stream_delay, |
+ kParameterNotSpecifiedValue, |
+ "Specify the stream delay in ms to use"); |
+DEFINE_int32(stream_drift_samples, |
+ kParameterNotSpecifiedValue, |
+ "Specify the number of stream drift samples to use"); |
+DEFINE_bool(performance_report, false, "Report the APM performance "); |
+DEFINE_bool(verbose, false, "Produce verbose output"); |
+DEFINE_bool(bitexactness_report, |
+ false, |
+ "Report bitexactness for aec dump result reproduction"); |
+DEFINE_bool(discard_settings_in_aecdump, |
+ false, |
+ "Discard any config settings specified in the aec dump"); |
+DEFINE_bool(store_intermediate_output, |
+ false, |
+ "Creates new output files after each init"); |
+ |
+void SetSettingIfSpecified(const std::string value, |
+ rtc::Optional<std::string>* parameter) { |
+ if (value.compare("") != 0) { |
+ *parameter = rtc::Optional<std::string>(value); |
+ } |
} |
-} // namespace |
+void SetSettingIfSpecified(int value, rtc::Optional<int>* parameter) { |
+ if (value != kParameterNotSpecifiedValue) { |
+ *parameter = rtc::Optional<int>(value); |
+ } |
+} |
-DEFINE_string(dump, "", "Name of the aecdump debug file to read from."); |
-DEFINE_string(i, "", "Name of the capture input stream file to read from."); |
-DEFINE_string( |
- o, |
- "out.wav", |
- "Name of the output file to write the processed capture stream to."); |
-DEFINE_string(ri, "", "Name of the render input stream file to read from."); |
-DEFINE_string( |
- ro, |
- "out_reverse.wav", |
- "Name of the output file to write the processed render stream to."); |
-DEFINE_int32(out_channels, 1, "Number of output channels."); |
-const bool out_channels_dummy = |
- google::RegisterFlagValidator(&FLAGS_out_channels, &ValidateOutChannels); |
-DEFINE_int32(rev_out_channels, 1, "Number of reverse output channels."); |
-const bool rev_out_channels_dummy = |
- google::RegisterFlagValidator(&FLAGS_rev_out_channels, |
- &ValidateOutChannels); |
-DEFINE_int32(out_sample_rate, 48000, "Output sample rate in Hz."); |
-DEFINE_int32(rev_out_sample_rate, 48000, "Reverse output sample rate in Hz."); |
-DEFINE_string(mic_positions, "", |
- "Space delimited cartesian coordinates of microphones in meters. " |
- "The coordinates of each point are contiguous. " |
- "For a two element array: \"x1 y1 z1 x2 y2 z2\""); |
-DEFINE_double( |
- target_angle_degrees, |
- 90, |
- "The azimuth of the target in degrees. Only applies to beamforming."); |
- |
-DEFINE_bool(aec, false, "Enable echo cancellation."); |
-DEFINE_bool(agc, false, "Enable automatic gain control."); |
-DEFINE_bool(hpf, false, "Enable high-pass filtering."); |
-DEFINE_bool(ns, false, "Enable noise suppression."); |
-DEFINE_bool(ts, false, "Enable transient suppression."); |
-DEFINE_bool(bf, false, "Enable beamforming."); |
-DEFINE_bool(ie, false, "Enable intelligibility enhancer."); |
-DEFINE_bool(all, false, "Enable all components."); |
- |
-DEFINE_int32(ns_level, -1, "Noise suppression level [0 - 3]."); |
- |
-DEFINE_bool(perf, false, "Enable performance tests."); |
+void SetSettingIfFlagSet(bool condition, |
+ rtc::Optional<bool>* parameter, |
+ bool value_to_set) { |
+ if (condition) { |
+ *parameter = rtc::Optional<bool>(value_to_set); |
+ } |
+} |
-namespace webrtc { |
-namespace { |
+SimulationSettings CreateSettings() { |
+ SimulationSettings settings; |
+ if (FLAGS_all_default) { |
+ settings.use_le = rtc::Optional<bool>(true); |
+ settings.use_vad = rtc::Optional<bool>(true); |
+ settings.use_ie = rtc::Optional<bool>(false); |
+ settings.use_bf = rtc::Optional<bool>(false); |
+ settings.use_ts = rtc::Optional<bool>(true); |
+ settings.use_ns = rtc::Optional<bool>(true); |
+ settings.use_hpf = rtc::Optional<bool>(true); |
+ settings.use_agc = rtc::Optional<bool>(true); |
+ settings.use_aec = rtc::Optional<bool>(true); |
+ settings.use_aecm = rtc::Optional<bool>(false); |
+ } |
+ SetSettingIfSpecified(FLAGS_dump_input, &settings.aec_dump_input_filename); |
+ SetSettingIfSpecified(FLAGS_dump_output, &settings.aec_dump_output_filename); |
+ SetSettingIfSpecified(FLAGS_i, &settings.input_filename); |
+ SetSettingIfSpecified(FLAGS_o, &settings.output_filename); |
+ SetSettingIfSpecified(FLAGS_ri, &settings.reverse_input_filename); |
+ SetSettingIfSpecified(FLAGS_ro, &settings.reverse_output_filename); |
+ SetSettingIfSpecified(FLAGS_output_num_channels, |
+ &settings.output_num_channels); |
+ SetSettingIfSpecified(FLAGS_reverse_output_num_channels, |
+ &settings.reverse_output_num_channels); |
+ SetSettingIfSpecified(FLAGS_output_sample_rate_hz, |
+ &settings.output_sample_rate_hz); |
+ SetSettingIfSpecified(FLAGS_reverse_output_sample_rate_hz, |
+ &settings.reverse_output_sample_rate_hz); |
+ SetSettingIfSpecified(FLAGS_mic_positions, &settings.microphone_positions); |
+ settings.target_angle_degrees = FLAGS_target_angle_degrees; |
+ SetSettingIfFlagSet(FLAGS_aec, &settings.use_aec, true); |
+ SetSettingIfFlagSet(FLAGS_no_aec, &settings.use_aec, false); |
+ SetSettingIfFlagSet(FLAGS_aecm, &settings.use_aecm, true); |
+ SetSettingIfFlagSet(FLAGS_no_aecm, &settings.use_aecm, false); |
+ SetSettingIfFlagSet(FLAGS_agc, &settings.use_agc, true); |
+ SetSettingIfFlagSet(FLAGS_no_agc, &settings.use_agc, false); |
+ SetSettingIfFlagSet(FLAGS_hpf, &settings.use_hpf, true); |
+ SetSettingIfFlagSet(FLAGS_no_hpf, &settings.use_hpf, false); |
+ SetSettingIfFlagSet(FLAGS_ns, &settings.use_ns, true); |
+ SetSettingIfFlagSet(FLAGS_no_ns, &settings.use_ns, false); |
+ SetSettingIfFlagSet(FLAGS_ts, &settings.use_ts, true); |
+ SetSettingIfFlagSet(FLAGS_no_ts, &settings.use_ts, false); |
+ SetSettingIfFlagSet(FLAGS_bf, &settings.use_bf, true); |
+ SetSettingIfFlagSet(FLAGS_no_bf, &settings.use_bf, false); |
+ SetSettingIfFlagSet(FLAGS_ie, &settings.use_ie, true); |
+ SetSettingIfFlagSet(FLAGS_no_ie, &settings.use_ie, false); |
+ SetSettingIfFlagSet(FLAGS_vad, &settings.use_vad, true); |
+ SetSettingIfFlagSet(FLAGS_no_vad, &settings.use_vad, false); |
+ SetSettingIfFlagSet(FLAGS_le, &settings.use_le, true); |
+ SetSettingIfFlagSet(FLAGS_no_le, &settings.use_le, false); |
+ SetSettingIfSpecified(FLAGS_aec_suppression_level, |
+ &settings.aec_suppression_level); |
+ SetSettingIfFlagSet(FLAGS_delay_agnostic, &settings.use_delay_agnostic, true); |
+ SetSettingIfFlagSet(FLAGS_no_delay_agnostic, &settings.use_delay_agnostic, |
+ false); |
+ SetSettingIfFlagSet(FLAGS_extended_filter, &settings.use_extended_filter, |
+ true); |
+ SetSettingIfFlagSet(FLAGS_no_extended_filter, &settings.use_extended_filter, |
+ false); |
+ SetSettingIfFlagSet(FLAGS_drift_compensation, |
+ &settings.use_drift_compensation, true); |
+ SetSettingIfFlagSet(FLAGS_no_drift_compensation, |
+ &settings.use_drift_compensation, false); |
+ SetSettingIfFlagSet(FLAGS_refined_adaptive_filter, |
+ &settings.use_refined_adaptive_filter, true); |
+ SetSettingIfFlagSet(FLAGS_no_refined_adaptive_filter, |
+ &settings.use_refined_adaptive_filter, false); |
-const int kChunksPerSecond = 100; |
-const char kUsage[] = |
- "Command-line tool to run audio processing on WAV files. Accepts either\n" |
- "an input capture WAV file or protobuf debug dump and writes to an output\n" |
- "WAV file.\n" |
- "\n" |
- "All components are disabled by default."; |
+ SetSettingIfFlagSet(FLAGS_aec3, &settings.use_aec3, true); |
+ SetSettingIfFlagSet(FLAGS_no_aec3, &settings.use_aec3, false); |
+ SetSettingIfSpecified(FLAGS_aecm_routing_mode, &settings.aecm_routing_mode); |
+ SetSettingIfFlagSet(FLAGS_aecm_comfort_noise, |
+ &settings.use_aecm_comfort_noise, true); |
+ SetSettingIfFlagSet(FLAGS_no_aecm_comfort_noise, |
+ &settings.use_aecm_comfort_noise, false); |
+ SetSettingIfSpecified(FLAGS_agc_mode, &settings.agc_mode); |
+ SetSettingIfSpecified(FLAGS_agc_target_level, &settings.agc_target_level); |
+ SetSettingIfFlagSet(FLAGS_agc_limiter, &settings.use_agc_limiter, true); |
+ SetSettingIfFlagSet(FLAGS_no_agc_limiter, &settings.use_agc_limiter, false); |
+ SetSettingIfSpecified(FLAGS_agc_compression_gain, |
+ &settings.agc_compression_gain); |
+ SetSettingIfSpecified(FLAGS_vad_likelihood, &settings.vad_likelihood); |
+ SetSettingIfSpecified(FLAGS_ns_level, &settings.ns_level); |
+ SetSettingIfSpecified(FLAGS_stream_delay, &settings.stream_delay); |
+ SetSettingIfSpecified(FLAGS_stream_drift_samples, |
+ &settings.stream_drift_samples); |
+ settings.report_performance = FLAGS_performance_report; |
+ settings.use_verbose_logging = FLAGS_verbose; |
+ settings.report_bitexactness = FLAGS_bitexactness_report; |
+ settings.discard_all_settings_in_aecdump = FLAGS_discard_settings_in_aecdump; |
+ settings.fixed_interface = FLAGS_fixed_interface; |
+ settings.store_intermediate_output = FLAGS_store_intermediate_output; |
-} // namespace |
+ return settings; |
+} |
-int main(int argc, char* argv[]) { |
- google::SetUsageMessage(kUsage); |
- google::ParseCommandLineFlags(&argc, &argv, true); |
+void ReportConditionalErrorAndExit(bool condition, std::string message) { |
+ if (condition) { |
+ fprintf(stderr, "%s", message.c_str()); |
+ exit(1); |
+ } |
+} |
+ |
+void PerformBasicParameterSanityChecks(const SimulationSettings& settings) { |
+ if (settings.input_filename || settings.reverse_input_filename) { |
+ ReportConditionalErrorAndExit(!!settings.aec_dump_input_filename, |
+ "Error: The aec dump cannot be specified " |
+ "together with input wav files!\n"); |
- if (!((FLAGS_i.empty()) ^ (FLAGS_dump.empty()))) { |
- fprintf(stderr, |
- "An input file must be specified with either -i or -dump.\n"); |
- return 1; |
+ ReportConditionalErrorAndExit(!settings.input_filename, |
+ "Error: When operating at wav files, the " |
+ "input wav filename must be " |
+ "specified!\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.reverse_output_filename && !settings.reverse_input_filename, |
+ "Error: When operating at wav files, the reverse input wav filename " |
+ "must be specified if the reverse output wav filename is specified!\n"); |
+ } else { |
+ ReportConditionalErrorAndExit(!settings.aec_dump_input_filename, |
+ "Error: Either the aec dump or the wav " |
+ "input files must be specified!\n"); |
} |
- test::TraceToStderr trace_to_stderr(true); |
- Config config; |
- if (FLAGS_bf || FLAGS_all) { |
- if (FLAGS_mic_positions.empty()) { |
- fprintf(stderr, "-mic_positions must be specified when -bf is used.\n"); |
- return 1; |
+ ReportConditionalErrorAndExit( |
+ settings.use_aec && *settings.use_aec && settings.use_aecm && |
+ *settings.use_aecm, |
+ "Error: The AEC and the AECM cannot be activated at the same time!\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.output_sample_rate_hz && *settings.output_sample_rate_hz <= 0, |
+ "Error: --output_sample_rate_hz must be positive!\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.reverse_output_sample_rate_hz && |
+ settings.output_sample_rate_hz && |
+ *settings.output_sample_rate_hz <= 0, |
+ "Error: --reverse_output_sample_rate_hz must be positive!\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.output_num_channels && *settings.output_num_channels <= 0, |
+ "Error: --output_num_channels must be positive!\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.reverse_output_num_channels && |
+ *settings.reverse_output_num_channels <= 0, |
+ "Error: --reverse_output_num_channels must be positive!\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.use_bf && *settings.use_bf && !settings.microphone_positions, |
+ "Error: --mic_positions must be specified when the beamformer is " |
+ "activated.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.target_angle_degrees < 0 || settings.target_angle_degrees > 359, |
+ "Error: -target_angle_degrees must be specified between 0 and 359.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.aec_suppression_level && |
+ ((*settings.aec_suppression_level) < 0 || |
+ (*settings.aec_suppression_level) > 2), |
+ "Error: --aec_suppression_level must be specified between 0 and 2.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.aecm_routing_mode && ((*settings.aecm_routing_mode) < 0 || |
+ (*settings.aecm_routing_mode) > 4), |
+ "Error: --aecm_routing_mode must be specified between 0 and 4.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.agc_target_level && ((*settings.agc_target_level) < 0 || |
+ (*settings.agc_target_level) > 31), |
+ "Error: --agc_target_level must be specified between 0 and 31.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.agc_compression_gain && ((*settings.agc_compression_gain) < 0 || |
+ (*settings.agc_compression_gain) > 90), |
+ "Error: --agc_compression_gain must be specified between 0 and 90.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.vad_likelihood && |
+ ((*settings.vad_likelihood) < 0 || (*settings.vad_likelihood) > 3), |
+ "Error: --vad_likelihood must be specified between 0 and 3.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.ns_level && |
+ ((*settings.ns_level) < 0 || (*settings.ns_level) > 3), |
+ "Error: --ns_level must be specified between 0 and 3.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.report_bitexactness && !settings.aec_dump_input_filename, |
+ "Error: --bitexactness_report can only be used when operating on an " |
+ "aecdump\n"); |
+ |
+ auto valid_wav_name = [](const std::string& wav_file_name) { |
+ if (wav_file_name.size() < 5) { |
+ return false; |
} |
- config.Set<Beamforming>(new Beamforming( |
- true, ParseArrayGeometry(FLAGS_mic_positions), |
- SphericalPointf(DegreesToRadians(FLAGS_target_angle_degrees), 0.f, |
- 1.f))); |
- } |
- config.Set<ExperimentalNs>(new ExperimentalNs(FLAGS_ts || FLAGS_all)); |
- config.Set<Intelligibility>(new Intelligibility(FLAGS_ie || FLAGS_all)); |
- |
- std::unique_ptr<AudioProcessing> ap(AudioProcessing::Create(config)); |
- RTC_CHECK_EQ(kNoErr, ap->echo_cancellation()->Enable(FLAGS_aec || FLAGS_all)); |
- RTC_CHECK_EQ(kNoErr, ap->gain_control()->Enable(FLAGS_agc || FLAGS_all)); |
- RTC_CHECK_EQ(kNoErr, ap->high_pass_filter()->Enable(FLAGS_hpf || FLAGS_all)); |
- RTC_CHECK_EQ(kNoErr, ap->noise_suppression()->Enable(FLAGS_ns || FLAGS_all)); |
- if (FLAGS_ns_level != -1) { |
- RTC_CHECK_EQ(kNoErr, |
- ap->noise_suppression()->set_level( |
- static_cast<NoiseSuppression::Level>(FLAGS_ns_level))); |
- } |
- ap->set_stream_key_pressed(FLAGS_ts); |
- |
- std::unique_ptr<AudioFileProcessor> processor; |
- auto out_file = std::unique_ptr<WavWriter>(new WavWriter( |
- FLAGS_o, FLAGS_out_sample_rate, static_cast<size_t>(FLAGS_out_channels))); |
- std::cout << FLAGS_o << ": " << out_file->FormatAsString() << std::endl; |
- if (FLAGS_dump.empty()) { |
- auto in_file = std::unique_ptr<WavReader>(new WavReader(FLAGS_i)); |
- std::cout << FLAGS_i << ": " << in_file->FormatAsString() << std::endl; |
- std::unique_ptr<WavReader> reverse_in_file; |
- std::unique_ptr<WavWriter> reverse_out_file; |
- if (!FLAGS_ri.empty()) { |
- reverse_in_file.reset(new WavReader(FLAGS_ri)); |
- reverse_out_file.reset(new WavWriter( |
- FLAGS_ro, |
- FLAGS_rev_out_sample_rate, |
- static_cast<size_t>(FLAGS_rev_out_channels))); |
- std::cout << FLAGS_ri << ": " |
- << reverse_in_file->FormatAsString() << std::endl; |
- std::cout << FLAGS_ro << ": " |
- << reverse_out_file->FormatAsString() << std::endl; |
+ if ((wav_file_name.compare(wav_file_name.size() - 4, 4, ".wav") == 0) || |
+ (wav_file_name.compare(wav_file_name.size() - 4, 4, ".WAV") == 0)) { |
+ return true; |
} |
- processor.reset(new WavFileProcessor(std::move(ap), |
- std::move(in_file), |
- std::move(out_file), |
- std::move(reverse_in_file), |
- std::move(reverse_out_file))); |
+ return false; |
+ }; |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.input_filename && (!valid_wav_name(*settings.input_filename)), |
+ "Error: --i must be a valid .wav file name.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.output_filename && (!valid_wav_name(*settings.output_filename)), |
+ "Error: --o must be a valid .wav file name.\n"); |
+ ReportConditionalErrorAndExit( |
+ settings.reverse_input_filename && |
+ (!valid_wav_name(*settings.reverse_input_filename)), |
+ "Error: --ri must be a valid .wav file name.\n"); |
+ |
+ ReportConditionalErrorAndExit( |
+ settings.reverse_output_filename && |
+ (!valid_wav_name(*settings.reverse_output_filename)), |
+ "Error: --ro must be a valid .wav file name.\n"); |
+} |
+ |
+} // namespace |
+ |
+int main(int argc, char* argv[]) { |
+ google::SetUsageMessage(kUsageDescription); |
+ google::ParseCommandLineFlags(&argc, &argv, true); |
+ |
+ SimulationSettings settings = CreateSettings(); |
+ PerformBasicParameterSanityChecks(settings); |
+ std::unique_ptr<AudioProcessingSimulator> processor; |
+ |
+ if (settings.aec_dump_input_filename) { |
+ processor.reset(new AecDumpBasedSimulator(settings)); |
} else { |
- processor.reset(new AecDumpFileProcessor( |
- std::move(ap), fopen(FLAGS_dump.c_str(), "rb"), std::move(out_file))); |
+ processor.reset(new WavBasedSimulator(settings)); |
} |
- int num_chunks = 0; |
- while (processor->ProcessChunk()) { |
- trace_to_stderr.SetTimeSeconds(num_chunks * 1.f / kChunksPerSecond); |
- ++num_chunks; |
- } |
+ processor->Process(); |
- if (FLAGS_perf) { |
+ if (settings.report_performance) { |
const auto& proc_time = processor->proc_time(); |
int64_t exec_time_us = proc_time.sum.Microseconds(); |
printf( |
"\nExecution time: %.3f s, File time: %.2f s\n" |
- "Time per chunk (mean, max, min):\n%.0f us, %.0f us, %.0f us\n", |
- exec_time_us * 1e-6, num_chunks * 1.f / kChunksPerSecond, |
- exec_time_us * 1.f / num_chunks, 1.f * proc_time.max.Microseconds(), |
- 1.f * proc_time.min.Microseconds()); |
+ "Time per fwd stream chunk (mean, max, min):\n%.0f us, %.0f us, %.0f " |
+ "us\n", |
+ exec_time_us * 1e-6, processor->get_num_process_stream_calls() * 1.f / |
+ AudioProcessingSimulator::kChunksPerSecond, |
+ exec_time_us * 1.f / processor->get_num_process_stream_calls(), |
+ 1.f * proc_time.max.Microseconds(), 1.f * proc_time.min.Microseconds()); |
+ } |
+ |
+ if (settings.report_bitexactness && settings.aec_dump_input_filename) { |
+ if (processor->OutputWasBitexact()) { |
+ printf("The processing was bitexact.\n"); |
+ } else { |
+ printf("The processing was not bitexact.\n"); |
+ } |
} |
return 0; |
} |
+} // namespace test |
} // namespace webrtc |
int main(int argc, char* argv[]) { |
- return webrtc::main(argc, argv); |
+ return webrtc::test::main(argc, argv); |
} |