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
Review URL: https://codereview.webrtc.org/1423693008
Cr-Commit-Position: refs/heads/master@{#10523}
diff --git a/webrtc/common_audio/wav_file.cc b/webrtc/common_audio/wav_file.cc
index b14b620..8dae7d6 100644
--- a/webrtc/common_audio/wav_file.cc
+++ b/webrtc/common_audio/wav_file.cc
@@ -37,17 +37,9 @@
FILE* file_;
};
-std::string WavFile::FormatAsString() const {
- std::ostringstream s;
- s << "Sample rate: " << sample_rate() << " Hz, Channels: " << num_channels()
- << ", Duration: "
- << (1.f * num_samples()) / (num_channels() * sample_rate()) << " s";
- return s.str();
-}
-
WavReader::WavReader(const std::string& filename)
: file_handle_(fopen(filename.c_str(), "rb")) {
- RTC_CHECK(file_handle_) << "Could not open wav file for reading.";
+ RTC_CHECK(file_handle_ && "Could not open wav file for reading.");
ReadableWavFile readable(file_handle_);
WavFormat format;
@@ -104,7 +96,7 @@
num_channels_(num_channels),
num_samples_(0),
file_handle_(fopen(filename.c_str(), "wb")) {
- RTC_CHECK(file_handle_) << "Could not open wav file for writing.";
+ RTC_CHECK(file_handle_ && "Could not open wav file for writing.");
RTC_CHECK(CheckWavParameters(num_channels_, sample_rate_, kWavFormat,
kBytesPerSample, num_samples_));
diff --git a/webrtc/common_audio/wav_file.h b/webrtc/common_audio/wav_file.h
index 42b0618..2eadd3f 100644
--- a/webrtc/common_audio/wav_file.h
+++ b/webrtc/common_audio/wav_file.h
@@ -29,9 +29,6 @@
virtual int sample_rate() const = 0;
virtual int num_channels() const = 0;
virtual uint32_t num_samples() const = 0;
-
- // Returns a human-readable string containing the audio format.
- std::string FormatAsString() const;
};
// Simple C++ class for writing 16-bit PCM WAV files. All error handling is
diff --git a/webrtc/modules/audio_processing/audio_processing_tests.gypi b/webrtc/modules/audio_processing/audio_processing_tests.gypi
index b301b00..0314c69 100644
--- a/webrtc/modules/audio_processing/audio_processing_tests.gypi
+++ b/webrtc/modules/audio_processing/audio_processing_tests.gypi
@@ -12,13 +12,10 @@
'target_name': 'audioproc_test_utils',
'type': 'static_library',
'dependencies': [
- 'audioproc_debug_proto',
'<(webrtc_root)/base/base.gyp:rtc_base_approved',
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
],
'sources': [
- 'test/audio_file_processor.cc',
- 'test/audio_file_processor.h',
'test/test_utils.cc',
'test/test_utils.h',
],
diff --git a/webrtc/modules/audio_processing/test/audio_file_processor.cc b/webrtc/modules/audio_processing/test/audio_file_processor.cc
deleted file mode 100644
index ca244d5..0000000
--- a/webrtc/modules/audio_processing/test/audio_file_processor.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2015 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 "webrtc/modules/audio_processing/test/audio_file_processor.h"
-
-#include <algorithm>
-
-#include "webrtc/base/checks.h"
-#include "webrtc/modules/audio_processing/test/protobuf_utils.h"
-
-using rtc::scoped_ptr;
-using rtc::CheckedDivExact;
-using std::vector;
-using webrtc::audioproc::Event;
-using webrtc::audioproc::Init;
-using webrtc::audioproc::ReverseStream;
-using webrtc::audioproc::Stream;
-
-namespace webrtc {
-namespace {
-
-// Returns a StreamConfig corresponding to file.
-StreamConfig GetStreamConfig(const WavFile& file) {
- return StreamConfig(file.sample_rate(), file.num_channels());
-}
-
-// Returns a ChannelBuffer corresponding to file.
-ChannelBuffer<float> GetChannelBuffer(const WavFile& file) {
- return ChannelBuffer<float>(
- CheckedDivExact(file.sample_rate(), AudioFileProcessor::kChunksPerSecond),
- file.num_channels());
-}
-
-} // namespace
-
-WavFileProcessor::WavFileProcessor(scoped_ptr<AudioProcessing> ap,
- scoped_ptr<WavReader> in_file,
- scoped_ptr<WavWriter> out_file)
- : ap_(ap.Pass()),
- in_buf_(GetChannelBuffer(*in_file)),
- out_buf_(GetChannelBuffer(*out_file)),
- input_config_(GetStreamConfig(*in_file)),
- output_config_(GetStreamConfig(*out_file)),
- buffer_reader_(in_file.Pass()),
- buffer_writer_(out_file.Pass()) {}
-
-bool WavFileProcessor::ProcessChunk() {
- if (!buffer_reader_.Read(&in_buf_)) {
- return false;
- }
- {
- const auto st = ScopedTimer(mutable_proc_time());
- RTC_CHECK_EQ(kNoErr,
- ap_->ProcessStream(in_buf_.channels(), input_config_,
- output_config_, out_buf_.channels()));
- }
- buffer_writer_.Write(out_buf_);
- return true;
-}
-
-AecDumpFileProcessor::AecDumpFileProcessor(scoped_ptr<AudioProcessing> ap,
- FILE* dump_file,
- scoped_ptr<WavWriter> out_file)
- : ap_(ap.Pass()),
- dump_file_(dump_file),
- out_buf_(GetChannelBuffer(*out_file)),
- output_config_(GetStreamConfig(*out_file)),
- buffer_writer_(out_file.Pass()) {
- RTC_CHECK(dump_file_) << "Could not open dump file for reading.";
-}
-
-AecDumpFileProcessor::~AecDumpFileProcessor() {
- fclose(dump_file_);
-}
-
-bool AecDumpFileProcessor::ProcessChunk() {
- Event event_msg;
-
- // Continue until we process our first Stream message.
- do {
- if (!ReadMessageFromFile(dump_file_, &event_msg)) {
- return false;
- }
-
- if (event_msg.type() == Event::INIT) {
- RTC_CHECK(event_msg.has_init());
- HandleMessage(event_msg.init());
-
- } else if (event_msg.type() == Event::STREAM) {
- RTC_CHECK(event_msg.has_stream());
- HandleMessage(event_msg.stream());
-
- } else if (event_msg.type() == Event::REVERSE_STREAM) {
- RTC_CHECK(event_msg.has_reverse_stream());
- HandleMessage(event_msg.reverse_stream());
- }
- } while (event_msg.type() != Event::STREAM);
-
- return true;
-}
-
-void AecDumpFileProcessor::HandleMessage(const Init& msg) {
- RTC_CHECK(msg.has_sample_rate());
- RTC_CHECK(msg.has_num_input_channels());
- RTC_CHECK(msg.has_num_reverse_channels());
-
- in_buf_.reset(new ChannelBuffer<float>(
- CheckedDivExact(msg.sample_rate(), kChunksPerSecond),
- msg.num_input_channels()));
- const int reverse_sample_rate = msg.has_reverse_sample_rate()
- ? msg.reverse_sample_rate()
- : msg.sample_rate();
- reverse_buf_.reset(new ChannelBuffer<float>(
- CheckedDivExact(reverse_sample_rate, kChunksPerSecond),
- msg.num_reverse_channels()));
- input_config_ = StreamConfig(msg.sample_rate(), msg.num_input_channels());
- reverse_config_ =
- StreamConfig(reverse_sample_rate, msg.num_reverse_channels());
-
- const ProcessingConfig config = {
- {input_config_, output_config_, reverse_config_, reverse_config_}};
- RTC_CHECK_EQ(kNoErr, ap_->Initialize(config));
-}
-
-void AecDumpFileProcessor::HandleMessage(const Stream& msg) {
- RTC_CHECK(!msg.has_input_data());
- RTC_CHECK_EQ(in_buf_->num_channels(), msg.input_channel_size());
-
- for (int i = 0; i < msg.input_channel_size(); ++i) {
- RTC_CHECK_EQ(in_buf_->num_frames() * sizeof(*in_buf_->channels()[i]),
- msg.input_channel(i).size());
- std::memcpy(in_buf_->channels()[i], msg.input_channel(i).data(),
- msg.input_channel(i).size());
- }
- {
- const auto st = ScopedTimer(mutable_proc_time());
- RTC_CHECK_EQ(kNoErr, ap_->set_stream_delay_ms(msg.delay()));
- ap_->echo_cancellation()->set_stream_drift_samples(msg.drift());
- if (msg.has_keypress()) {
- ap_->set_stream_key_pressed(msg.keypress());
- }
- RTC_CHECK_EQ(kNoErr,
- ap_->ProcessStream(in_buf_->channels(), input_config_,
- output_config_, out_buf_.channels()));
- }
-
- buffer_writer_.Write(out_buf_);
-}
-
-void AecDumpFileProcessor::HandleMessage(const ReverseStream& msg) {
- RTC_CHECK(!msg.has_data());
- RTC_CHECK_EQ(reverse_buf_->num_channels(), msg.channel_size());
-
- for (int i = 0; i < msg.channel_size(); ++i) {
- RTC_CHECK_EQ(reverse_buf_->num_frames() * sizeof(*in_buf_->channels()[i]),
- msg.channel(i).size());
- std::memcpy(reverse_buf_->channels()[i], msg.channel(i).data(),
- msg.channel(i).size());
- }
- {
- const auto st = ScopedTimer(mutable_proc_time());
- // TODO(ajm): This currently discards the processed output, which is needed
- // for e.g. intelligibility enhancement.
- RTC_CHECK_EQ(kNoErr, ap_->ProcessReverseStream(
- reverse_buf_->channels(), reverse_config_,
- reverse_config_, reverse_buf_->channels()));
- }
-}
-
-} // namespace webrtc
diff --git a/webrtc/modules/audio_processing/test/audio_file_processor.h b/webrtc/modules/audio_processing/test/audio_file_processor.h
deleted file mode 100644
index a3153b2..0000000
--- a/webrtc/modules/audio_processing/test/audio_file_processor.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2015 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.
- */
-
-#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_TEST_AUDIO_FILE_PROCESSOR_H_
-#define WEBRTC_MODULES_AUDIO_PROCESSING_TEST_AUDIO_FILE_PROCESSOR_H_
-
-#include <algorithm>
-#include <limits>
-#include <vector>
-
-#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/test_utils.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-
-#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
-#include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h"
-#else
-#include "webrtc/audio_processing/debug.pb.h"
-#endif
-
-namespace webrtc {
-
-// Holds a few statistics about a series of TickIntervals.
-struct TickIntervalStats {
- TickIntervalStats() : min(std::numeric_limits<int64_t>::max()) {}
- TickInterval sum;
- TickInterval max;
- TickInterval min;
-};
-
-// Interface for processing an input file with an AudioProcessing instance and
-// dumping the results to an output file.
-class AudioFileProcessor {
- public:
- static const int kChunksPerSecond = 1000 / AudioProcessing::kChunkSizeMs;
-
- virtual ~AudioFileProcessor() {}
-
- // Processes one AudioProcessing::kChunkSizeMs of data from the input file and
- // writes to the output file.
- virtual bool ProcessChunk() = 0;
-
- // Returns the execution time of all AudioProcessing calls.
- const TickIntervalStats& proc_time() const { return proc_time_; }
-
- protected:
- // RAII class for execution time measurement. Updates the provided
- // TickIntervalStats based on the time between ScopedTimer creation and
- // leaving the enclosing scope.
- class ScopedTimer {
- public:
- explicit ScopedTimer(TickIntervalStats* proc_time)
- : proc_time_(proc_time), start_time_(TickTime::Now()) {}
-
- ~ScopedTimer() {
- TickInterval interval = TickTime::Now() - start_time_;
- proc_time_->sum += interval;
- proc_time_->max = std::max(proc_time_->max, interval);
- proc_time_->min = std::min(proc_time_->min, interval);
- }
-
- private:
- TickIntervalStats* const proc_time_;
- TickTime start_time_;
- };
-
- TickIntervalStats* mutable_proc_time() { return &proc_time_; }
-
- private:
- TickIntervalStats proc_time_;
-};
-
-// Used to read from and write to WavFile objects.
-class WavFileProcessor final : public AudioFileProcessor {
- public:
- // Takes ownership of all parameters.
- WavFileProcessor(rtc::scoped_ptr<AudioProcessing> ap,
- rtc::scoped_ptr<WavReader> in_file,
- rtc::scoped_ptr<WavWriter> out_file);
- virtual ~WavFileProcessor() {}
-
- // Processes one chunk from the WAV input and writes to the WAV output.
- bool ProcessChunk() override;
-
- private:
- rtc::scoped_ptr<AudioProcessing> ap_;
-
- ChannelBuffer<float> in_buf_;
- ChannelBuffer<float> out_buf_;
- const StreamConfig input_config_;
- const StreamConfig output_config_;
- ChannelBufferWavReader buffer_reader_;
- ChannelBufferWavWriter buffer_writer_;
-};
-
-// Used to read from an aecdump file and write to a WavWriter.
-class AecDumpFileProcessor final : public AudioFileProcessor {
- public:
- // Takes ownership of all parameters.
- AecDumpFileProcessor(rtc::scoped_ptr<AudioProcessing> ap,
- FILE* dump_file,
- rtc::scoped_ptr<WavWriter> out_file);
-
- virtual ~AecDumpFileProcessor();
-
- // Processes messages from the aecdump file until the first Stream message is
- // completed. Passes other data from the aecdump messages as appropriate.
- bool ProcessChunk() override;
-
- private:
- void HandleMessage(const webrtc::audioproc::Init& msg);
- void HandleMessage(const webrtc::audioproc::Stream& msg);
- void HandleMessage(const webrtc::audioproc::ReverseStream& msg);
-
- rtc::scoped_ptr<AudioProcessing> ap_;
- FILE* dump_file_;
-
- rtc::scoped_ptr<ChannelBuffer<float>> in_buf_;
- rtc::scoped_ptr<ChannelBuffer<float>> reverse_buf_;
- ChannelBuffer<float> out_buf_;
- StreamConfig input_config_;
- StreamConfig reverse_config_;
- const StreamConfig output_config_;
- ChannelBufferWavWriter buffer_writer_;
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_MODULES_AUDIO_PROCESSING_TEST_AUDIO_FILE_PROCESSOR_H_
diff --git a/webrtc/modules/audio_processing/test/audioproc_float.cc b/webrtc/modules/audio_processing/test/audioproc_float.cc
index 3f1dc37..27f69b3 100644
--- a/webrtc/modules/audio_processing/test/audioproc_float.cc
+++ b/webrtc/modules/audio_processing/test/audioproc_float.cc
@@ -9,7 +9,6 @@
*/
#include <stdio.h>
-#include <iostream>
#include <sstream>
#include <string>
@@ -19,28 +18,26 @@
#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(dump, "", "The name of the debug dump file to read from.");
+DEFINE_string(i, "", "The name of the input file to read from.");
+DEFINE_string(i_rev, "", "The name of the reverse input file to read from.");
+DEFINE_string(o, "out.wav", "Name of the output file to write to.");
+DEFINE_string(o_rev,
+ "out_rev.wav",
+ "Name of the reverse output file to write to.");
+DEFINE_int32(out_channels, 0, "Number of output channels. Defaults to input.");
+DEFINE_int32(out_sample_rate, 0,
+ "Output sample rate in Hz. Defaults to input.");
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_double(target_angle_degrees, 90, "The azimuth of the target in radians");
DEFINE_bool(aec, false, "Enable echo cancellation.");
DEFINE_bool(agc, false, "Enable automatic gain control.");
@@ -67,6 +64,15 @@
"All components are disabled by default. If any bi-directional components\n"
"are enabled, only debug dump files are permitted.";
+// Returns a StreamConfig corresponding to wav_file if it's non-nullptr.
+// Otherwise returns a default initialized StreamConfig.
+StreamConfig MakeStreamConfig(const WavFile* wav_file) {
+ if (wav_file) {
+ return {wav_file->sample_rate(), wav_file->num_channels()};
+ }
+ return {};
+}
+
} // namespace
int main(int argc, char* argv[]) {
@@ -78,75 +84,160 @@
"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");
+ if (!FLAGS_dump.empty()) {
+ fprintf(stderr, "FIXME: the -dump option is not yet implemented.\n");
return 1;
}
test::TraceToStderr trace_to_stderr(true);
+ WavReader in_file(FLAGS_i);
+ // If the output format is uninitialized, use the input format.
+ const int out_channels =
+ FLAGS_out_channels ? FLAGS_out_channels : in_file.num_channels();
+ const int out_sample_rate =
+ FLAGS_out_sample_rate ? FLAGS_out_sample_rate : in_file.sample_rate();
+ WavWriter out_file(FLAGS_o, out_sample_rate, out_channels);
+
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));
+ if (FLAGS_bf || FLAGS_all) {
+ const size_t num_mics = in_file.num_channels();
+ const std::vector<Point> array_geometry =
+ ParseArrayGeometry(FLAGS_mic_positions, num_mics);
+ RTC_CHECK_EQ(array_geometry.size(), num_mics);
+
+ config.Set<Beamforming>(new Beamforming(
+ true, array_geometry,
+ SphericalPointf(DegreesToRadians(FLAGS_target_angle_degrees), 0.f,
+ 1.f)));
+ }
+
rtc::scoped_ptr<AudioProcessing> ap(AudioProcessing::Create(config));
- RTC_CHECK_EQ(kNoErr, ap->echo_cancellation()->Enable(FLAGS_aec || FLAGS_all));
+ if (!FLAGS_dump.empty()) {
+ RTC_CHECK_EQ(kNoErr,
+ ap->echo_cancellation()->Enable(FLAGS_aec || FLAGS_all));
+ } else if (FLAGS_aec) {
+ fprintf(stderr, "-aec requires a -dump file.\n");
+ return -1;
+ }
+ bool process_reverse = !FLAGS_i_rev.empty();
RTC_CHECK_EQ(kNoErr, ap->gain_control()->Enable(FLAGS_agc || FLAGS_all));
+ RTC_CHECK_EQ(kNoErr,
+ ap->gain_control()->set_mode(GainControl::kFixedDigital));
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) {
+ 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(ap.Pass(), in_file.Pass(), out_file.Pass()));
+ printf("Input file: %s\nChannels: %d, Sample rate: %d Hz\n\n",
+ FLAGS_i.c_str(), in_file.num_channels(), in_file.sample_rate());
+ printf("Output file: %s\nChannels: %d, Sample rate: %d Hz\n\n",
+ FLAGS_o.c_str(), out_file.num_channels(), out_file.sample_rate());
- } else {
- processor.reset(new AecDumpFileProcessor(
- ap.Pass(), fopen(FLAGS_dump.c_str(), "rb"), out_file.Pass()));
+ ChannelBuffer<float> in_buf(
+ rtc::CheckedDivExact(in_file.sample_rate(), kChunksPerSecond),
+ in_file.num_channels());
+ ChannelBuffer<float> out_buf(
+ rtc::CheckedDivExact(out_file.sample_rate(), kChunksPerSecond),
+ out_file.num_channels());
+
+ std::vector<float> in_interleaved(in_buf.size());
+ std::vector<float> out_interleaved(out_buf.size());
+
+ rtc::scoped_ptr<WavReader> in_rev_file;
+ rtc::scoped_ptr<WavWriter> out_rev_file;
+ rtc::scoped_ptr<ChannelBuffer<float>> in_rev_buf;
+ rtc::scoped_ptr<ChannelBuffer<float>> out_rev_buf;
+ std::vector<float> in_rev_interleaved;
+ std::vector<float> out_rev_interleaved;
+ if (process_reverse) {
+ in_rev_file.reset(new WavReader(FLAGS_i_rev));
+ out_rev_file.reset(new WavWriter(FLAGS_o_rev, in_rev_file->sample_rate(),
+ in_rev_file->num_channels()));
+ printf("In rev file: %s\nChannels: %d, Sample rate: %d Hz\n\n",
+ FLAGS_i_rev.c_str(), in_rev_file->num_channels(),
+ in_rev_file->sample_rate());
+ printf("Out rev file: %s\nChannels: %d, Sample rate: %d Hz\n\n",
+ FLAGS_o_rev.c_str(), out_rev_file->num_channels(),
+ out_rev_file->sample_rate());
+ in_rev_buf.reset(new ChannelBuffer<float>(
+ rtc::CheckedDivExact(in_rev_file->sample_rate(), kChunksPerSecond),
+ in_rev_file->num_channels()));
+ in_rev_interleaved.resize(in_rev_buf->size());
+ out_rev_buf.reset(new ChannelBuffer<float>(
+ rtc::CheckedDivExact(out_rev_file->sample_rate(), kChunksPerSecond),
+ out_rev_file->num_channels()));
+ out_rev_interleaved.resize(out_rev_buf->size());
}
+ TickTime processing_start_time;
+ TickInterval accumulated_time;
int num_chunks = 0;
- while (processor->ProcessChunk()) {
+
+ const auto input_config = MakeStreamConfig(&in_file);
+ const auto output_config = MakeStreamConfig(&out_file);
+ const auto reverse_input_config = MakeStreamConfig(in_rev_file.get());
+ const auto reverse_output_config = MakeStreamConfig(out_rev_file.get());
+
+ while (in_file.ReadSamples(in_interleaved.size(),
+ &in_interleaved[0]) == in_interleaved.size()) {
+ // Have logs display the file time rather than wallclock time.
trace_to_stderr.SetTimeSeconds(num_chunks * 1.f / kChunksPerSecond);
- ++num_chunks;
- }
+ FloatS16ToFloat(&in_interleaved[0], in_interleaved.size(),
+ &in_interleaved[0]);
+ Deinterleave(&in_interleaved[0], in_buf.num_frames(),
+ in_buf.num_channels(), in_buf.channels());
+ if (process_reverse) {
+ in_rev_file->ReadSamples(in_rev_interleaved.size(),
+ in_rev_interleaved.data());
+ FloatS16ToFloat(in_rev_interleaved.data(), in_rev_interleaved.size(),
+ in_rev_interleaved.data());
+ Deinterleave(in_rev_interleaved.data(), in_rev_buf->num_frames(),
+ in_rev_buf->num_channels(), in_rev_buf->channels());
+ }
+ if (FLAGS_perf) {
+ processing_start_time = TickTime::Now();
+ }
+ RTC_CHECK_EQ(kNoErr, ap->ProcessStream(in_buf.channels(), input_config,
+ output_config, out_buf.channels()));
+ if (process_reverse) {
+ RTC_CHECK_EQ(kNoErr, ap->ProcessReverseStream(
+ in_rev_buf->channels(), reverse_input_config,
+ reverse_output_config, out_rev_buf->channels()));
+ }
+ if (FLAGS_perf) {
+ accumulated_time += TickTime::Now() - processing_start_time;
+ }
+
+ Interleave(out_buf.channels(), out_buf.num_frames(),
+ out_buf.num_channels(), &out_interleaved[0]);
+ FloatToFloatS16(&out_interleaved[0], out_interleaved.size(),
+ &out_interleaved[0]);
+ out_file.WriteSamples(&out_interleaved[0], out_interleaved.size());
+ if (process_reverse) {
+ Interleave(out_rev_buf->channels(), out_rev_buf->num_frames(),
+ out_rev_buf->num_channels(), out_rev_interleaved.data());
+ FloatToFloatS16(out_rev_interleaved.data(), out_rev_interleaved.size(),
+ out_rev_interleaved.data());
+ out_rev_file->WriteSamples(out_rev_interleaved.data(),
+ out_rev_interleaved.size());
+ }
+ 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());
+ int64_t execution_time_ms = accumulated_time.Milliseconds();
+ printf("\nExecution time: %.3f s\nFile time: %.2f s\n"
+ "Time per chunk: %.3f ms\n",
+ execution_time_ms * 0.001f, num_chunks * 1.f / kChunksPerSecond,
+ execution_time_ms * 1.f / num_chunks);
}
-
return 0;
}
diff --git a/webrtc/modules/audio_processing/test/process_test.cc b/webrtc/modules/audio_processing/test/process_test.cc
index 1383bbe..fdfaab0 100644
--- a/webrtc/modules/audio_processing/test/process_test.cc
+++ b/webrtc/modules/audio_processing/test/process_test.cc
@@ -636,8 +636,8 @@
}
if (!raw_output) {
- // The WAV file needs to be reset every time, because it can't change
- // its sample rate or number of channels.
+ // The WAV file needs to be reset every time, because it cant change
+ // it's sample rate or number of channels.
output_wav_file.reset(new WavWriter(out_filename + ".wav",
output_sample_rate,
msg.num_output_channels()));
diff --git a/webrtc/modules/audio_processing/test/test_utils.cc b/webrtc/modules/audio_processing/test/test_utils.cc
index 47bd314..1b9ac3c 100644
--- a/webrtc/modules/audio_processing/test/test_utils.cc
+++ b/webrtc/modules/audio_processing/test/test_utils.cc
@@ -31,35 +31,6 @@
fwrite(samples, sizeof(*samples), num_samples, file_handle_);
}
-ChannelBufferWavReader::ChannelBufferWavReader(rtc::scoped_ptr<WavReader> file)
- : file_(file.Pass()) {}
-
-bool ChannelBufferWavReader::Read(ChannelBuffer<float>* buffer) {
- RTC_CHECK_EQ(file_->num_channels(), buffer->num_channels());
- interleaved_.resize(buffer->size());
- if (file_->ReadSamples(interleaved_.size(), &interleaved_[0]) !=
- interleaved_.size()) {
- return false;
- }
-
- FloatS16ToFloat(&interleaved_[0], interleaved_.size(), &interleaved_[0]);
- Deinterleave(&interleaved_[0], buffer->num_frames(), buffer->num_channels(),
- buffer->channels());
- return true;
-}
-
-ChannelBufferWavWriter::ChannelBufferWavWriter(rtc::scoped_ptr<WavWriter> file)
- : file_(file.Pass()) {}
-
-void ChannelBufferWavWriter::Write(const ChannelBuffer<float>& buffer) {
- RTC_CHECK_EQ(file_->num_channels(), buffer.num_channels());
- interleaved_.resize(buffer.size());
- Interleave(buffer.channels(), buffer.num_frames(), buffer.num_channels(),
- &interleaved_[0]);
- FloatToFloatS16(&interleaved_[0], interleaved_.size(), &interleaved_[0]);
- file_->WriteSamples(&interleaved_[0], interleaved_.size());
-}
-
void WriteIntData(const int16_t* data,
size_t length,
WavWriter* wav_file,
@@ -121,32 +92,28 @@
case 2:
return AudioProcessing::kStereo;
default:
- RTC_CHECK(false);
+ assert(false);
return AudioProcessing::kMono;
}
}
-std::vector<Point> ParseArrayGeometry(const std::string& mic_positions) {
+std::vector<Point> ParseArrayGeometry(const std::string& mic_positions,
+ size_t num_mics) {
const std::vector<float> values = ParseList<float>(mic_positions);
- const size_t num_mics =
- rtc::CheckedDivExact(values.size(), static_cast<size_t>(3));
- RTC_CHECK_GT(num_mics, 0u) << "mic_positions is not large enough.";
+ RTC_CHECK_EQ(values.size(), 3 * num_mics)
+ << "Could not parse mic_positions or incorrect number of points.";
std::vector<Point> result;
result.reserve(num_mics);
for (size_t i = 0; i < values.size(); i += 3) {
- result.push_back(Point(values[i + 0], values[i + 1], values[i + 2]));
+ double x = values[i + 0];
+ double y = values[i + 1];
+ double z = values[i + 2];
+ result.push_back(Point(x, y, z));
}
return result;
}
-std::vector<Point> ParseArrayGeometry(const std::string& mic_positions,
- size_t num_mics) {
- std::vector<Point> result = ParseArrayGeometry(mic_positions);
- RTC_CHECK_EQ(result.size(), num_mics)
- << "Could not parse mic_positions or incorrect number of points.";
- return result;
-}
} // namespace webrtc
diff --git a/webrtc/modules/audio_processing/test/test_utils.h b/webrtc/modules/audio_processing/test/test_utils.h
index 93a0138..75e4239 100644
--- a/webrtc/modules/audio_processing/test/test_utils.h
+++ b/webrtc/modules/audio_processing/test/test_utils.h
@@ -43,35 +43,6 @@
RTC_DISALLOW_COPY_AND_ASSIGN(RawFile);
};
-// Reads ChannelBuffers from a provided WavReader.
-class ChannelBufferWavReader final {
- public:
- explicit ChannelBufferWavReader(rtc::scoped_ptr<WavReader> file);
-
- // Reads data from the file according to the |buffer| format. Returns false if
- // a full buffer can't be read from the file.
- bool Read(ChannelBuffer<float>* buffer);
-
- private:
- rtc::scoped_ptr<WavReader> file_;
- std::vector<float> interleaved_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(ChannelBufferWavReader);
-};
-
-// Writes ChannelBuffers to a provided WavWriter.
-class ChannelBufferWavWriter final {
- public:
- explicit ChannelBufferWavWriter(rtc::scoped_ptr<WavWriter> file);
- void Write(const ChannelBuffer<float>& buffer);
-
- private:
- rtc::scoped_ptr<WavWriter> file_;
- std::vector<float> interleaved_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(ChannelBufferWavWriter);
-};
-
void WriteIntData(const int16_t* data,
size_t length,
WavWriter* wav_file,
@@ -147,9 +118,6 @@
std::vector<Point> ParseArrayGeometry(const std::string& mic_positions,
size_t num_mics);
-// Same as above, but without the num_mics check for when it isn't available.
-std::vector<Point> ParseArrayGeometry(const std::string& mic_positions);
-
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_TEST_TEST_UTILS_H_
diff --git a/webrtc/system_wrappers/include/tick_util.h b/webrtc/system_wrappers/include/tick_util.h
index 46d62cc..f839ff6 100644
--- a/webrtc/system_wrappers/include/tick_util.h
+++ b/webrtc/system_wrappers/include/tick_util.h
@@ -83,7 +83,6 @@
class TickInterval {
public:
TickInterval();
- explicit TickInterval(int64_t interval);
int64_t Milliseconds() const;
int64_t Microseconds() const;
@@ -104,6 +103,8 @@
friend bool operator>=(const TickInterval& lhs, const TickInterval& rhs);
private:
+ explicit TickInterval(int64_t interval);
+
friend class TickTime;
friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);