Reland: Add IntelligibilityEnhancer support to audioproc_float

Landed originally here: https://codereview.webrtc.org/1800413002/

TBR=peah@webrtc.org

Review URL: https://codereview.webrtc.org/1843823002 .

Cr-Commit-Position: refs/heads/master@{#12150}
This commit is contained in:
Alejandro Luebs 2016-03-29 14:54:37 -07:00
parent d45b95c270
commit af2f3dd206
3 changed files with 81 additions and 16 deletions

View File

@ -42,14 +42,39 @@ ChannelBuffer<float> GetChannelBuffer(const WavFile& file) {
WavFileProcessor::WavFileProcessor(std::unique_ptr<AudioProcessing> ap,
std::unique_ptr<WavReader> in_file,
std::unique_ptr<WavWriter> out_file)
std::unique_ptr<WavWriter> out_file,
std::unique_ptr<WavReader> reverse_in_file,
std::unique_ptr<WavWriter> reverse_out_file)
: ap_(std::move(ap)),
in_buf_(GetChannelBuffer(*in_file)),
out_buf_(GetChannelBuffer(*out_file)),
input_config_(GetStreamConfig(*in_file)),
output_config_(GetStreamConfig(*out_file)),
buffer_reader_(std::move(in_file)),
buffer_writer_(std::move(out_file)) {}
buffer_writer_(std::move(out_file)) {
if (reverse_in_file) {
const WavFile* reverse_out_config;
if (reverse_out_file) {
reverse_out_config = reverse_out_file.get();
} else {
reverse_out_config = reverse_in_file.get();
}
reverse_in_buf_.reset(
new ChannelBuffer<float>(GetChannelBuffer(*reverse_in_file)));
reverse_out_buf_.reset(
new ChannelBuffer<float>(GetChannelBuffer(*reverse_out_config)));
reverse_input_config_.reset(
new StreamConfig(GetStreamConfig(*reverse_in_file)));
reverse_output_config_.reset(
new StreamConfig(GetStreamConfig(*reverse_out_config)));
reverse_buffer_reader_.reset(
new ChannelBufferWavReader(std::move(reverse_in_file)));
if (reverse_out_file) {
reverse_buffer_writer_.reset(
new ChannelBufferWavWriter(std::move(reverse_out_file)));
}
}
}
bool WavFileProcessor::ProcessChunk() {
if (!buffer_reader_.Read(&in_buf_)) {
@ -62,6 +87,22 @@ bool WavFileProcessor::ProcessChunk() {
output_config_, out_buf_.channels()));
}
buffer_writer_.Write(out_buf_);
if (reverse_buffer_reader_) {
if (!reverse_buffer_reader_->Read(reverse_in_buf_.get())) {
return false;
}
{
const auto st = ScopedTimer(mutable_proc_time());
RTC_CHECK_EQ(kNoErr,
ap_->ProcessReverseStream(reverse_in_buf_->channels(),
*reverse_input_config_.get(),
*reverse_output_config_.get(),
reverse_out_buf_->channels()));
}
if (reverse_buffer_writer_) {
reverse_buffer_writer_->Write(*reverse_out_buf_.get());
}
}
return true;
}

View File

@ -86,7 +86,9 @@ class WavFileProcessor final : public AudioFileProcessor {
// Takes ownership of all parameters.
WavFileProcessor(std::unique_ptr<AudioProcessing> ap,
std::unique_ptr<WavReader> in_file,
std::unique_ptr<WavWriter> out_file);
std::unique_ptr<WavWriter> out_file,
std::unique_ptr<WavReader> reverse_in_file,
std::unique_ptr<WavWriter> reverse_out_file);
virtual ~WavFileProcessor() {}
// Processes one chunk from the WAV input and writes to the WAV output.
@ -101,6 +103,12 @@ class WavFileProcessor final : public AudioFileProcessor {
const StreamConfig output_config_;
ChannelBufferWavReader buffer_reader_;
ChannelBufferWavWriter buffer_writer_;
std::unique_ptr<ChannelBuffer<float>> reverse_in_buf_;
std::unique_ptr<ChannelBuffer<float>> reverse_out_buf_;
std::unique_ptr<StreamConfig> reverse_input_config_;
std::unique_ptr<StreamConfig> reverse_output_config_;
std::unique_ptr<ChannelBufferWavReader> reverse_buffer_reader_;
std::unique_ptr<ChannelBufferWavWriter> reverse_buffer_writer_;
};
// Used to read from an aecdump file and write to a WavWriter.

View File

@ -42,10 +42,20 @@ DEFINE_string(
o,
"out.wav",
"Name of the output file to write the processed capture stream to.");
DEFINE_string(ri, "", "Name of the render input stream file to read from.");
DEFINE_string(
ro,
"out_reverse.wav",
"Name of the output file to write the processed render stream to.");
DEFINE_int32(out_channels, 1, "Number of output channels.");
const bool out_channels_dummy =
google::RegisterFlagValidator(&FLAGS_out_channels, &ValidateOutChannels);
DEFINE_int32(rev_out_channels, 1, "Number of reverse output channels.");
const bool rev_out_channels_dummy =
google::RegisterFlagValidator(&FLAGS_rev_out_channels,
&ValidateOutChannels);
DEFINE_int32(out_sample_rate, 48000, "Output sample rate in Hz.");
DEFINE_int32(rev_out_sample_rate, 48000, "Reverse output sample rate in Hz.");
DEFINE_string(mic_positions, "",
"Space delimited cartesian coordinates of microphones in meters. "
"The coordinates of each point are contiguous. "
@ -77,8 +87,7 @@ const char kUsage[] =
"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.";
"All components are disabled by default.";
} // namespace
@ -91,15 +100,6 @@ int main(int argc, char* argv[]) {
"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;
@ -135,8 +135,24 @@ int main(int argc, char* argv[]) {
if (FLAGS_dump.empty()) {
auto in_file = std::unique_ptr<WavReader>(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)));
std::unique_ptr<WavReader> reverse_in_file;
std::unique_ptr<WavWriter> reverse_out_file;
if (!FLAGS_ri.empty()) {
reverse_in_file.reset(new WavReader(FLAGS_ri));
reverse_out_file.reset(new WavWriter(
FLAGS_ro,
FLAGS_rev_out_sample_rate,
static_cast<size_t>(FLAGS_rev_out_channels)));
std::cout << FLAGS_ri << ": "
<< reverse_in_file->FormatAsString() << std::endl;
std::cout << FLAGS_ro << ": "
<< reverse_out_file->FormatAsString() << std::endl;
}
processor.reset(new WavFileProcessor(std::move(ap),
std::move(in_file),
std::move(out_file),
std::move(reverse_in_file),
std::move(reverse_out_file)));
} else {
processor.reset(new AecDumpFileProcessor(