170 lines
6.1 KiB
C++
Raw Normal View History

/*
* 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/format_macros.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"
namespace {
bool ValidateOutChannels(const char* flagname, int32_t value) {
return value >= 0;
}
} // namespace
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.");
const bool out_channels_dummy =
google::RegisterFlagValidator(&FLAGS_out_channels, &ValidateOutChannels);
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));
Reland of Add aecdump support to audioproc_f. (patchset #2 id:250001 of https://codereview.webrtc.org/1423693008/ ) Reason for revert: Oh dear, this broke compilation. I guess more was built on top of this CL before I reverted it. Reverting now for futher investigation (and re-land using CQ) Original issue's description: > Revert of Add aecdump support to audioproc_f. (patchset #8 id:200001 of https://codereview.webrtc.org/1409943002/ ) > > Reason for revert: > This breaks iOS GYP generation as described on http://www.webrtc.org/native-code/ios > I'm going to drive getting the build_with_libjingle=1 setting removed from the bots to match the official instructions. > > See https://code.google.com/p/webrtc/issues/detail?id=4653 for more context, as this is exactly what that issue tries to solve. > > Original issue's description: > > Add aecdump support to audioproc_f. > > > > Add a new interface to abstract away file operations. This CL temporarily > > removes support for dumping the output of reverse streams. It will be easy to > > restore in the new framework, although we may decide to only allow it with > > the aecdump format. > > > > We also now require the user to specify the output format, rather than > > defaulting to the input format. > > > > TEST=Bit-exact output to the previous audioproc_f version using an input wav > > file, and to the legacy audioproc using an aecdump file. > > > > Committed: https://crrev.com/bdafe31b86e9819b0adb9041f87e6194b7422b08 > > Cr-Commit-Position: refs/heads/master@{#10460} > > TBR=aluebs@webrtc.org,peah@webrtc.org,andrew@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > > Committed: https://crrev.com/d279941bb54bfdc6e7324bf36cac76581474b96d > Cr-Commit-Position: refs/heads/master@{#10523} TBR=aluebs@webrtc.org,peah@webrtc.org,andrew@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Review URL: https://codereview.webrtc.org/1419953010 Cr-Commit-Position: refs/heads/master@{#10524}
2015-11-05 06:23:02 -08:00
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, static_cast<size_t>(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;
Revert of Add aecdump support to audioproc_f. (patchset #8 id:200001 of https://codereview.webrtc.org/1409943002/ ) This is the second revert. The first attempt in https://codereview.webrtc.org/1423693008/ was missing a subtle curly brace caused by a merge conflict. I'm going to let this one go through the CQ. Reason for revert: This breaks iOS GYP generation as described on http://www.webrtc.org/native-code/ios I'm going to drive getting the build_with_libjingle=1 setting removed from the bots to match the official instructions. See https://code.google.com/p/webrtc/issues/detail?id=4653 for more context, as this is exactly what that issue tries to solve. Original issue's description: > Add aecdump support to audioproc_f. > > Add a new interface to abstract away file operations. This CL temporarily > removes support for dumping the output of reverse streams. It will be easy to > restore in the new framework, although we may decide to only allow it with > the aecdump format. > > We also now require the user to specify the output format, rather than > defaulting to the input format. > > TEST=Bit-exact output to the previous audioproc_f version using an input wav > file, and to the legacy audioproc using an aecdump file. > > Committed: https://crrev.com/bdafe31b86e9819b0adb9041f87e6194b7422b08 > Cr-Commit-Position: refs/heads/master@{#10460} TBR=aluebs@webrtc.org,peah@webrtc.org,andrew@webrtc.org BUG= Review URL: https://codereview.webrtc.org/1412963007 Cr-Commit-Position: refs/heads/master@{#10532}
2015-11-05 12:33:18 -08:00
}
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);
}