| /* |
| * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include <stdio.h> |
| #include <iostream> |
| #include <sstream> |
| #include <string> |
| #include <utility> |
| |
| #include "gflags/gflags.h" |
| #include "webrtc/base/checks.h" |
| #include "webrtc/base/scoped_ptr.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" |
| |
| 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_int32(out_channels, 1, "Number of output channels."); |
| DEFINE_int32(out_sample_rate, 48000, "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."); |
| |
| namespace webrtc { |
| namespace { |
| |
| 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. If any bi-directional components\n" |
| "are enabled, only debug dump files are permitted."; |
| |
| } // namespace |
| |
| int main(int argc, char* argv[]) { |
| google::SetUsageMessage(kUsage); |
| google::ParseCommandLineFlags(&argc, &argv, true); |
| |
| if (!((FLAGS_i.empty()) ^ (FLAGS_dump.empty()))) { |
| fprintf(stderr, |
| "An input file must be specified with either -i or -dump.\n"); |
| return 1; |
| } |
| if (FLAGS_dump.empty() && (FLAGS_aec || FLAGS_ie)) { |
| fprintf(stderr, "-aec and -ie require a -dump file.\n"); |
| return 1; |
| } |
| if (FLAGS_ie) { |
| fprintf(stderr, |
| "FIXME(ajm): The intelligibility enhancer output is not dumped.\n"); |
| return 1; |
| } |
| |
| 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; |
| } |
| 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)); |
| |
| rtc::scoped_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); |
| |
| rtc::scoped_ptr<AudioFileProcessor> processor; |
| auto out_file = rtc_make_scoped_ptr( |
| new WavWriter(FLAGS_o, FLAGS_out_sample_rate, FLAGS_out_channels)); |
| std::cout << FLAGS_o << ": " << out_file->FormatAsString() << std::endl; |
| if (FLAGS_dump.empty()) { |
| auto in_file = rtc_make_scoped_ptr(new WavReader(FLAGS_i)); |
| std::cout << FLAGS_i << ": " << in_file->FormatAsString() << std::endl; |
| processor.reset(new WavFileProcessor(std::move(ap), std::move(in_file), |
| std::move(out_file))); |
| |
| } else { |
| processor.reset(new AecDumpFileProcessor( |
| std::move(ap), fopen(FLAGS_dump.c_str(), "rb"), std::move(out_file))); |
| } |
| |
| int num_chunks = 0; |
| while (processor->ProcessChunk()) { |
| trace_to_stderr.SetTimeSeconds(num_chunks * 1.f / kChunksPerSecond); |
| ++num_chunks; |
| } |
| |
| if (FLAGS_perf) { |
| 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()); |
| } |
| |
| return 0; |
| } |
| |
| } // namespace webrtc |
| |
| int main(int argc, char* argv[]) { |
| return webrtc::main(argc, argv); |
| } |