/* * 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. */ #ifndef MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_SIMULATOR_H_ #define MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_SIMULATOR_H_ #include #include #include #include #include #include "api/optional.h" #include "common_audio/channel_buffer.h" #include "modules/audio_processing/include/audio_processing.h" #include "modules/audio_processing/test/fake_recording_device.h" #include "modules/audio_processing/test/test_utils.h" #include "rtc_base/constructormagic.h" #include "rtc_base/task_queue.h" #include "rtc_base/timeutils.h" namespace webrtc { namespace test { // Holds all the parameters available for controlling the simulation. struct SimulationSettings { SimulationSettings(); SimulationSettings(const SimulationSettings&); ~SimulationSettings(); rtc::Optional stream_delay; rtc::Optional stream_drift_samples; rtc::Optional output_sample_rate_hz; rtc::Optional output_num_channels; rtc::Optional reverse_output_sample_rate_hz; rtc::Optional reverse_output_num_channels; rtc::Optional microphone_positions; int target_angle_degrees = 90; rtc::Optional output_filename; rtc::Optional reverse_output_filename; rtc::Optional input_filename; rtc::Optional reverse_input_filename; rtc::Optional artificial_nearend_filename; rtc::Optional use_aec; rtc::Optional use_aecm; rtc::Optional use_ed; // Residual Echo Detector. rtc::Optional ed_graph_output_filename; rtc::Optional use_agc; rtc::Optional use_agc2; rtc::Optional use_hpf; rtc::Optional use_ns; rtc::Optional use_ts; rtc::Optional use_bf; rtc::Optional use_ie; rtc::Optional use_vad; rtc::Optional use_le; rtc::Optional use_all; rtc::Optional aec_suppression_level; rtc::Optional use_delay_agnostic; rtc::Optional use_extended_filter; rtc::Optional use_drift_compensation; rtc::Optional use_aec3; rtc::Optional use_experimental_agc; rtc::Optional aecm_routing_mode; rtc::Optional use_aecm_comfort_noise; rtc::Optional agc_mode; rtc::Optional agc_target_level; rtc::Optional use_agc_limiter; rtc::Optional agc_compression_gain; float agc2_fixed_gain_db; rtc::Optional vad_likelihood; rtc::Optional ns_level; rtc::Optional use_refined_adaptive_filter; int initial_mic_level; bool simulate_mic_gain = false; rtc::Optional simulated_mic_kind; bool report_performance = false; bool report_bitexactness = false; bool use_verbose_logging = false; bool discard_all_settings_in_aecdump = true; rtc::Optional aec_dump_input_filename; rtc::Optional aec_dump_output_filename; bool fixed_interface = false; bool store_intermediate_output = false; rtc::Optional custom_call_order_filename; rtc::Optional aec3_settings_filename; }; // Holds a few statistics about a series of TickIntervals. struct TickIntervalStats { TickIntervalStats() : min(std::numeric_limits::max()) {} int64_t sum; int64_t max; int64_t min; }; // Copies samples present in a ChannelBuffer into an AudioFrame. void CopyToAudioFrame(const ChannelBuffer& src, AudioFrame* dest); // Provides common functionality for performing audioprocessing simulations. class AudioProcessingSimulator { public: static const int kChunksPerSecond = 1000 / AudioProcessing::kChunkSizeMs; AudioProcessingSimulator(const SimulationSettings& settings, std::unique_ptr ap_builder); virtual ~AudioProcessingSimulator(); // Processes the data in the input. virtual void Process() = 0; // Returns the execution time of all AudioProcessing calls. const TickIntervalStats& proc_time() const { return proc_time_; } // Reports whether the processed recording was bitexact. bool OutputWasBitexact() { return bitexact_output_; } size_t get_num_process_stream_calls() { return num_process_stream_calls_; } size_t get_num_reverse_process_stream_calls() { return num_reverse_process_stream_calls_; } 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_(rtc::TimeNanos()) {} ~ScopedTimer(); private: TickIntervalStats* const proc_time_; int64_t start_time_; }; TickIntervalStats* mutable_proc_time() { return &proc_time_; } void ProcessStream(bool fixed_interface); void ProcessReverseStream(bool fixed_interface); void CreateAudioProcessor(); void DestroyAudioProcessor(); void 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); const SimulationSettings settings_; std::unique_ptr ap_; std::unique_ptr ap_builder_; std::unique_ptr> in_buf_; std::unique_ptr> out_buf_; std::unique_ptr> reverse_in_buf_; std::unique_ptr> reverse_out_buf_; StreamConfig in_config_; StreamConfig out_config_; StreamConfig reverse_in_config_; StreamConfig reverse_out_config_; std::unique_ptr buffer_reader_; std::unique_ptr reverse_buffer_reader_; AudioFrame rev_frame_; AudioFrame fwd_frame_; bool bitexact_output_ = true; int aec_dump_mic_level_ = 0; private: void SetupOutput(); size_t num_process_stream_calls_ = 0; size_t num_reverse_process_stream_calls_ = 0; size_t output_reset_counter_ = 0; std::unique_ptr buffer_writer_; std::unique_ptr reverse_buffer_writer_; TickIntervalStats proc_time_; std::ofstream residual_echo_likelihood_graph_writer_; int analog_mic_level_; FakeRecordingDevice fake_recording_device_; rtc::TaskQueue worker_queue_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioProcessingSimulator); }; } // namespace test } // namespace webrtc #endif // MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_SIMULATOR_H_