Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Unified Diff: webrtc/modules/audio_processing/test/audio_processing_simulator.cc

Issue 1907223003: Extension and refactoring of the audioproc_f tool to be a fully fledged tool for audio processing m… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Changes in response to reviewer comments Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_processing/test/audio_processing_simulator.cc
diff --git a/webrtc/modules/audio_processing/test/audio_processing_simulator.cc b/webrtc/modules/audio_processing/test/audio_processing_simulator.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2f7a6e0337b6ab2e0d86fe7748f243f81a25c977
--- /dev/null
+++ b/webrtc/modules/audio_processing/test/audio_processing_simulator.cc
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2016 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_processing_simulator.h"
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "webrtc/base/stringutils.h"
+#include "webrtc/common_audio/include/audio_util.h"
+#include "webrtc/modules/audio_processing/include/audio_processing.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+void CopyFromAudioFrame(const AudioFrame& src, ChannelBuffer<float>* dest) {
+ RTC_CHECK_EQ(src.num_channels_, dest->num_channels());
+ RTC_CHECK_EQ(src.samples_per_channel_, dest->num_frames());
+ // Copy the data from the input buffer.
+ std::vector<float> tmp(src.samples_per_channel_ * src.num_channels_);
+ S16ToFloat(src.data_, tmp.size(), tmp.data());
+ Deinterleave(tmp.data(), src.samples_per_channel_, src.num_channels_,
+ dest->channels());
+}
+
+std::string GetIndexedOutputWavFilename(const std::string& wav_name,
+ int counter) {
+ std::stringstream ss;
+ ss << wav_name.substr(0, wav_name.size() - 4) << "_" << counter
+ << wav_name.substr(wav_name.size() - 4);
+ return ss.str();
+}
+
+} // namespace
+
+void CopyToAudioFrame(const ChannelBuffer<float>& src, AudioFrame* dest) {
+ RTC_CHECK_EQ(src.num_channels(), dest->num_channels_);
+ RTC_CHECK_EQ(src.num_frames(), dest->samples_per_channel_);
+ for (size_t ch = 0; ch < dest->num_channels_; ++ch) {
+ for (size_t sample = 0; sample < dest->samples_per_channel_; ++sample) {
+ dest->data_[sample * dest->num_channels_ + ch] =
+ src.channels()[ch][sample] * 32767;
+ }
+ }
+}
+
+AudioProcessingSimulator::ScopedTimer::~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);
+}
+
+void AudioProcessingSimulator::ProcessStream(bool fixed_interface) {
+ if (fixed_interface) {
+ {
+ const auto st = ScopedTimer(mutable_proc_time());
+ RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->ProcessStream(&fwd_frame_));
+ }
+ CopyFromAudioFrame(fwd_frame_, out_buf_.get());
+ } else {
+ const auto st = ScopedTimer(mutable_proc_time());
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->ProcessStream(in_buf_->channels(), in_config_,
+ out_config_, out_buf_->channels()));
+ }
+
+ if (buffer_writer_) {
+ buffer_writer_->Write(*out_buf_);
+ }
+
+ ++num_process_stream_calls_;
+}
+
+void AudioProcessingSimulator::ProcessReverseStream(bool fixed_interface) {
+ if (fixed_interface) {
+ const auto st = ScopedTimer(mutable_proc_time());
+ RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->ProcessStream(&rev_frame_));
+ CopyFromAudioFrame(rev_frame_, reverse_out_buf_.get());
+
+ } else {
+ const auto st = ScopedTimer(mutable_proc_time());
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->ProcessReverseStream(
+ reverse_in_buf_->channels(), reverse_in_config_,
+ reverse_out_config_, reverse_out_buf_->channels()));
+ }
+
+ if (reverse_buffer_writer_) {
+ reverse_buffer_writer_->Write(*reverse_out_buf_);
+ }
+
+ ++num_reverse_process_stream_calls_;
+}
+
+void AudioProcessingSimulator::SetupBuffersConfigsOutputs(
+ int input_sample_rate_hz,
+ int output_sample_rate_hz,
+ int reverse_input_sample_rate_hz,
+ int reverse_output_sample_rate_hz,
+ int input_num_channels,
+ int output_num_channels,
+ int reverse_input_num_channels,
+ int reverse_output_num_channels) {
+ in_config_ = StreamConfig(input_sample_rate_hz, input_num_channels);
+ in_buf_.reset(new ChannelBuffer<float>(
+ rtc::CheckedDivExact(input_sample_rate_hz, kChunksPerSecond),
+ input_num_channels));
+
+ reverse_in_config_ =
+ StreamConfig(reverse_input_sample_rate_hz, reverse_input_num_channels);
+ reverse_in_buf_.reset(new ChannelBuffer<float>(
+ rtc::CheckedDivExact(reverse_input_sample_rate_hz, kChunksPerSecond),
+ reverse_input_num_channels));
+
+ out_config_ = StreamConfig(output_sample_rate_hz, output_num_channels);
+ out_buf_.reset(new ChannelBuffer<float>(
+ rtc::CheckedDivExact(output_sample_rate_hz, kChunksPerSecond),
+ output_num_channels));
+
+ reverse_out_config_ =
+ StreamConfig(reverse_output_sample_rate_hz, reverse_output_num_channels);
+ reverse_out_buf_.reset(new ChannelBuffer<float>(
+ rtc::CheckedDivExact(reverse_output_sample_rate_hz, kChunksPerSecond),
+ reverse_output_num_channels));
+
+ fwd_frame_.sample_rate_hz_ = input_sample_rate_hz;
+ fwd_frame_.samples_per_channel_ =
+ rtc::CheckedDivExact(fwd_frame_.sample_rate_hz_, kChunksPerSecond);
+ fwd_frame_.num_channels_ = input_num_channels;
+
+ rev_frame_.sample_rate_hz_ = reverse_input_sample_rate_hz;
+ rev_frame_.samples_per_channel_ =
+ rtc::CheckedDivExact(rev_frame_.sample_rate_hz_, kChunksPerSecond);
+ rev_frame_.num_channels_ = reverse_input_num_channels;
+
+ if (settings_.use_verbose_logging) {
+ printf("Sample rates:\n");
+ printf(" Forward input: %d\n", input_sample_rate_hz);
+ printf(" Forward output: %d\n", output_sample_rate_hz);
+ printf(" Reverse input: %d\n", reverse_input_sample_rate_hz);
+ printf(" Reverse output: %d\n", reverse_output_sample_rate_hz);
+ printf("Number of channels:\n");
+ printf(" Forward input: %d\n", input_num_channels);
+ printf(" Forward output: %d\n", output_num_channels);
+ printf(" Reverse input: %d\n", reverse_input_num_channels);
+ printf(" Reverse output: %d\n", reverse_output_num_channels);
+ }
+
+ SetupOutput();
+}
+
+void AudioProcessingSimulator::SetupOutput() {
+ if (settings_.output_filename) {
+ std::string filename;
+ if (settings_.store_intermediate_output) {
+ filename = GetIndexedOutputWavFilename(*settings_.output_filename,
+ output_reset_counter_);
+ } else {
+ filename = *settings_.output_filename;
+ }
+
+ std::unique_ptr<WavWriter> out_file(
+ new WavWriter(filename, out_config_.sample_rate_hz(),
+ static_cast<size_t>(out_config_.num_channels())));
+ buffer_writer_.reset(new ChannelBufferWavWriter(std::move(out_file)));
+ }
+
+ if (settings_.reverse_output_filename) {
+ std::string filename;
+ if (settings_.store_intermediate_output) {
+ filename = GetIndexedOutputWavFilename(*settings_.reverse_output_filename,
+ output_reset_counter_);
+ } else {
+ filename = *settings_.reverse_output_filename;
+ }
+
+ std::unique_ptr<WavWriter> reverse_out_file(
+ new WavWriter(filename, reverse_out_config_.sample_rate_hz(),
+ static_cast<size_t>(reverse_out_config_.num_channels())));
+ reverse_buffer_writer_.reset(
+ new ChannelBufferWavWriter(std::move(reverse_out_file)));
+ }
+
+ ++output_reset_counter_;
+}
+
+void AudioProcessingSimulator::DestroyAudioProcessor() {
+ if (settings_.aec_dump_output_filename) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->StopDebugRecording());
+ }
+}
+
+void AudioProcessingSimulator::CreateAudioProcessor() {
+ Config config;
+ if (settings_.use_bf && *settings_.use_bf) {
+ config.Set<Beamforming>(new Beamforming(
+ true, ParseArrayGeometry(*settings_.microphone_positions),
+ SphericalPointf(DegreesToRadians(settings_.target_angle_degrees), 0.f,
+ 1.f)));
+ }
+ if (settings_.use_ts) {
+ config.Set<ExperimentalNs>(new ExperimentalNs(*settings_.use_ts));
+ }
+ if (settings_.use_ie) {
+ config.Set<Intelligibility>(new Intelligibility(*settings_.use_ie));
+ }
+ if (settings_.use_aec3) {
+ config.Set<EchoCanceller3>(new EchoCanceller3(*settings_.use_aec3));
+ }
+ if (settings_.use_refined_adaptive_filter) {
+ config.Set<RefinedAdaptiveFilter>(
+ new RefinedAdaptiveFilter(*settings_.use_refined_adaptive_filter));
+ }
+ config.Set<ExtendedFilter>(new ExtendedFilter(
+ !settings_.use_extended_filter || *settings_.use_extended_filter));
+ config.Set<DelayAgnostic>(new DelayAgnostic(!settings_.use_delay_agnostic ||
+ *settings_.use_delay_agnostic));
+
+ ap_.reset(AudioProcessing::Create(config));
+
+ if (settings_.use_aec) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->echo_cancellation()->Enable(*settings_.use_aec));
+ }
+ if (settings_.use_aecm) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->echo_control_mobile()->Enable(*settings_.use_aecm));
+ }
+ if (settings_.use_agc) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->gain_control()->Enable(*settings_.use_agc));
+ }
+ if (settings_.use_hpf) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->high_pass_filter()->Enable(*settings_.use_hpf));
+ }
+ if (settings_.use_ns) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->noise_suppression()->Enable(*settings_.use_ns));
+ }
+ if (settings_.use_le) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->level_estimator()->Enable(*settings_.use_le));
+ }
+ if (settings_.use_vad) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->voice_detection()->Enable(*settings_.use_vad));
+ }
+ if (settings_.use_agc_limiter) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->gain_control()->enable_limiter(
+ *settings_.use_agc_limiter));
+ }
+ if (settings_.agc_target_level) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->gain_control()->set_target_level_dbfs(
+ *settings_.agc_target_level));
+ }
+
+ if (settings_.agc_mode) {
+ RTC_CHECK_EQ(
+ AudioProcessing::kNoError,
+ ap_->gain_control()->set_mode(
+ static_cast<webrtc::GainControl::Mode>(*settings_.agc_mode)));
+ }
+
+ if (settings_.use_drift_compensation) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->echo_cancellation()->enable_drift_compensation(
+ *settings_.use_drift_compensation));
+ }
+
+ if (settings_.aec_suppression_level) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->echo_cancellation()->set_suppression_level(
+ static_cast<webrtc::EchoCancellation::SuppressionLevel>(
+ *settings_.aec_suppression_level)));
+ }
+
+ if (settings_.aecm_routing_mode) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->echo_control_mobile()->set_routing_mode(
+ static_cast<webrtc::EchoControlMobile::RoutingMode>(
+ *settings_.aecm_routing_mode)));
+ }
+
+ if (settings_.use_aecm_comfort_noise) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->echo_control_mobile()->enable_comfort_noise(
+ *settings_.use_aecm_comfort_noise));
+ }
+
+ if (settings_.vad_likelihood) {
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->voice_detection()->set_likelihood(
+ static_cast<webrtc::VoiceDetection::Likelihood>(
+ *settings_.vad_likelihood)));
+ }
+ if (settings_.ns_level) {
+ RTC_CHECK_EQ(
+ AudioProcessing::kNoError,
+ ap_->noise_suppression()->set_level(
+ static_cast<NoiseSuppression::Level>(*settings_.ns_level)));
+ }
+
+ if (settings_.use_ts) {
+ ap_->set_stream_key_pressed(*settings_.use_ts);
+ }
+
+ if (settings_.aec_dump_output_filename) {
+ size_t kMaxFilenameSize = AudioProcessing::kMaxFilenameSize;
+ RTC_CHECK_LE(settings_.aec_dump_output_filename->size(), kMaxFilenameSize);
+ RTC_CHECK_EQ(AudioProcessing::kNoError,
+ ap_->StartDebugRecording(
+ settings_.aec_dump_output_filename->c_str(), -1));
+ }
+}
+
+} // namespace test
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698