1/* 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include <vector> 12 13#include "gflags/gflags.h" 14#include "webrtc/base/checks.h" 15#include "webrtc/base/format_macros.h" 16#include "webrtc/common_audio/channel_buffer.h" 17#include "webrtc/common_audio/wav_file.h" 18#include "webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.h" 19#include "webrtc/modules/audio_processing/test/test_utils.h" 20 21DEFINE_string(i, "", "The name of the input file to read from."); 22DEFINE_string(o, "out.wav", "Name of the output file to write to."); 23DEFINE_string(mic_positions, "", 24 "Space delimited cartesian coordinates of microphones in meters. " 25 "The coordinates of each point are contiguous. " 26 "For a two element array: \"x1 y1 z1 x2 y2 z2\""); 27 28namespace webrtc { 29namespace { 30 31const int kChunksPerSecond = 100; 32const int kChunkSizeMs = 1000 / kChunksPerSecond; 33 34const char kUsage[] = 35 "Command-line tool to run beamforming on WAV files. The signal is passed\n" 36 "in as a single band, unlike the audio processing interface which splits\n" 37 "signals into multiple bands."; 38 39} // namespace 40 41int main(int argc, char* argv[]) { 42 google::SetUsageMessage(kUsage); 43 google::ParseCommandLineFlags(&argc, &argv, true); 44 45 WavReader in_file(FLAGS_i); 46 WavWriter out_file(FLAGS_o, in_file.sample_rate(), 1); 47 48 const size_t num_mics = in_file.num_channels(); 49 const std::vector<Point> array_geometry = 50 ParseArrayGeometry(FLAGS_mic_positions, num_mics); 51 RTC_CHECK_EQ(array_geometry.size(), num_mics); 52 53 NonlinearBeamformer bf(array_geometry); 54 bf.Initialize(kChunkSizeMs, in_file.sample_rate()); 55 56 printf("Input file: %s\nChannels: %" PRIuS ", Sample rate: %d Hz\n\n", 57 FLAGS_i.c_str(), in_file.num_channels(), in_file.sample_rate()); 58 printf("Output file: %s\nChannels: %" PRIuS ", Sample rate: %d Hz\n\n", 59 FLAGS_o.c_str(), out_file.num_channels(), out_file.sample_rate()); 60 61 ChannelBuffer<float> in_buf( 62 rtc::CheckedDivExact(in_file.sample_rate(), kChunksPerSecond), 63 in_file.num_channels()); 64 ChannelBuffer<float> out_buf( 65 rtc::CheckedDivExact(out_file.sample_rate(), kChunksPerSecond), 66 out_file.num_channels()); 67 68 std::vector<float> interleaved(in_buf.size()); 69 while (in_file.ReadSamples(interleaved.size(), 70 &interleaved[0]) == interleaved.size()) { 71 FloatS16ToFloat(&interleaved[0], interleaved.size(), &interleaved[0]); 72 Deinterleave(&interleaved[0], in_buf.num_frames(), 73 in_buf.num_channels(), in_buf.channels()); 74 75 bf.ProcessChunk(in_buf, &out_buf); 76 77 Interleave(out_buf.channels(), out_buf.num_frames(), 78 out_buf.num_channels(), &interleaved[0]); 79 FloatToFloatS16(&interleaved[0], interleaved.size(), &interleaved[0]); 80 out_file.WriteSamples(&interleaved[0], interleaved.size()); 81 } 82 83 return 0; 84} 85 86} // namespace webrtc 87 88int main(int argc, char* argv[]) { 89 return webrtc::main(argc, argv); 90} 91