From 4ddde2e3ada36ebeca6e53f8562eae4085ebc9fc Mon Sep 17 00:00:00 2001 From: "mgraczyk@chromium.org" Date: Thu, 29 Jan 2015 22:39:44 +0000 Subject: [PATCH] Add arbitrary microphone geometry input to audioproc_f test utility. R=andrew@webrtc.org Review URL: https://webrtc-codereview.appspot.com/35889004 Cr-Commit-Position: refs/heads/master@{#8208} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8208 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../audio_processing/test/audioproc_float.cc | 79 ++++++++++++++++--- 1 file changed, 67 insertions(+), 12 deletions(-) diff --git a/webrtc/modules/audio_processing/test/audioproc_float.cc b/webrtc/modules/audio_processing/test/audioproc_float.cc index f8059de6bd..bbac9f1c91 100644 --- a/webrtc/modules/audio_processing/test/audioproc_float.cc +++ b/webrtc/modules/audio_processing/test/audioproc_float.cc @@ -9,6 +9,7 @@ */ #include +#include #include #include "gflags/gflags.h" @@ -25,7 +26,12 @@ DEFINE_string(o, "out.wav", "Name of the capture output file to write to."); DEFINE_int32(o_channels, 0, "Number of output channels. Defaults to input."); DEFINE_int32(o_sample_rate, 0, "Output sample rate in Hz. Defaults to input."); DEFINE_double(mic_spacing, 0.0, - "Microphone spacing in meters. Used when beamforming is enabled"); + "Alternate way to specify mic_positions. " + "Assumes uniform linear array with specified spacings."); +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_bool(aec, false, "Enable echo cancellation."); DEFINE_bool(agc, false, "Enable automatic gain control."); @@ -48,6 +54,63 @@ static const char kUsage[] = namespace webrtc { +namespace { + +// Returns a vector parsed from whitespace delimited values in to_parse, +// or an empty vector if the string could not be parsed. +template +std::vector parse_list(std::string to_parse) { + std::vector values; + + std::istringstream str(to_parse); + std::copy( + std::istream_iterator(str), + std::istream_iterator(), + std::back_inserter(values)); + + return values; +} + +// Parses the array geometry from the command line. +// +// If a vector with size != num_mics is returned, an error has occurred and an +// appropriate error message has been printed to stdout. +std::vector get_array_geometry(size_t num_mics) { + std::vector result; + result.reserve(num_mics); + + if (FLAGS_mic_positions.length()) { + CHECK(FLAGS_mic_spacing == 0.0 && + "mic_positions and mic_spacing should not both be specified"); + + const std::vector values = parse_list(FLAGS_mic_positions); + if (values.size() != 3 * num_mics) { + fprintf(stderr, + "Could not parse mic_positions or incorrect number of points.\n"); + } else { + for (size_t i = 0; i < values.size(); i += 3) { + double x = values[i + 0]; + double y = values[i + 1]; + double z = values[i + 2]; + result.push_back(Point(x, y, z)); + } + } + } else { + if (FLAGS_mic_spacing <= 0) { + fprintf(stderr, + "mic_spacing must a positive value when beamforming is enabled.\n"); + } else { + for (size_t i = 0; i < num_mics; ++i) { + result.push_back(Point(0.0, i * FLAGS_mic_spacing, 0.0)); + } + } + } + + return result; +} + +} // namespace + int main(int argc, char* argv[]) { { const std::string program_name = argv[0]; @@ -80,18 +143,10 @@ int main(int argc, char* argv[]) { config.Set(new ExperimentalNs(FLAGS_ts || FLAGS_all)); if (FLAGS_bf || FLAGS_all) { - if (FLAGS_mic_spacing <= 0) { - fprintf(stderr, - "mic_spacing must a positive value when beamforming is enabled.\n"); - return 1; - } - const size_t num_mics = c_file.num_channels(); - std::vector array_geometry; - array_geometry.reserve(num_mics); - - for (size_t i = 0; i < num_mics; ++i) { - array_geometry.push_back(Point(0.0, i * FLAGS_mic_spacing, 0.0)); + const std::vector array_geometry = get_array_geometry(num_mics); + if (array_geometry.size() != num_mics) { + return 1; } config.Set(new Beamforming(true, array_geometry));