audio_processing_simulator.h (9730B)
1 /* 2 * Copyright (c) 2016 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 #ifndef MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_SIMULATOR_H_ 12 #define MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_SIMULATOR_H_ 13 14 #include <array> 15 #include <cstddef> 16 #include <cstdint> 17 #include <fstream> 18 #include <memory> 19 #include <optional> 20 #include <string> 21 #include <vector> 22 23 #include "absl/base/nullability.h" 24 #include "absl/strings/string_view.h" 25 #include "api/audio/audio_processing.h" 26 #include "api/scoped_refptr.h" 27 #include "common_audio/channel_buffer.h" 28 #include "common_audio/include/audio_util.h" 29 #include "common_audio/wav_file.h" 30 #include "modules/audio_processing/test/api_call_statistics.h" 31 #include "modules/audio_processing/test/fake_recording_device.h" 32 #include "modules/audio_processing/test/test_utils.h" 33 #include "rtc_base/checks.h" 34 #include "rtc_base/task_queue_for_test.h" 35 36 namespace webrtc { 37 namespace test { 38 39 static const int kChunksPerSecond = 1000 / AudioProcessing::kChunkSizeMs; 40 41 struct Int16Frame { 42 void SetFormat(int sample_rate_hz, int num_channels) { 43 sample_rate_hz_ = sample_rate_hz; 44 samples_per_channel_ = CheckedDivExact(sample_rate_hz, kChunksPerSecond); 45 num_channels_ = num_channels; 46 config = StreamConfig(sample_rate_hz, num_channels); 47 data.resize(num_channels * samples_per_channel_); 48 } 49 50 void CopyTo(ChannelBuffer<float>* dest) { 51 RTC_DCHECK(dest); 52 RTC_CHECK_EQ(num_channels_, dest->num_channels()); 53 RTC_CHECK_EQ(samples_per_channel_, dest->num_frames()); 54 // Copy the data from the input buffer. 55 std::vector<float> tmp(samples_per_channel_ * num_channels_); 56 S16ToFloat(data.data(), tmp.size(), tmp.data()); 57 Deinterleave(tmp.data(), samples_per_channel_, num_channels_, 58 dest->channels()); 59 } 60 61 void CopyFrom(const ChannelBuffer<float>& src) { 62 RTC_CHECK_EQ(src.num_channels(), num_channels_); 63 RTC_CHECK_EQ(src.num_frames(), samples_per_channel_); 64 data.resize(num_channels_ * samples_per_channel_); 65 int16_t* dest_data = data.data(); 66 for (int ch = 0; ch < num_channels_; ++ch) { 67 for (int sample = 0; sample < samples_per_channel_; ++sample) { 68 dest_data[sample * num_channels_ + ch] = 69 src.channels()[ch][sample] * 32767; 70 } 71 } 72 } 73 74 int sample_rate_hz_; 75 int samples_per_channel_; 76 int num_channels_; 77 78 StreamConfig config; 79 80 std::vector<int16_t> data; 81 }; 82 83 // Holds all the parameters available for controlling the simulation. 84 struct SimulationSettings { 85 SimulationSettings(); 86 SimulationSettings(const SimulationSettings&); 87 ~SimulationSettings(); 88 std::optional<int> stream_delay; 89 std::optional<bool> use_stream_delay; 90 std::optional<int> output_sample_rate_hz; 91 std::optional<int> output_num_channels; 92 std::optional<int> reverse_output_sample_rate_hz; 93 std::optional<int> reverse_output_num_channels; 94 std::optional<std::string> output_filename; 95 std::optional<std::string> reverse_output_filename; 96 std::optional<std::string> input_filename; 97 std::optional<std::string> reverse_input_filename; 98 std::optional<std::string> artificial_nearend_filename; 99 std::optional<std::string> linear_aec_output_filename; 100 std::optional<bool> use_aec; 101 std::optional<bool> use_aecm; 102 std::optional<bool> use_ed; // Residual Echo Detector. 103 std::optional<std::string> ed_graph_output_filename; 104 std::optional<bool> use_agc; 105 std::optional<bool> use_agc2; 106 std::optional<bool> use_pre_amplifier; 107 std::optional<bool> use_capture_level_adjustment; 108 std::optional<bool> use_analog_mic_gain_emulation; 109 std::optional<bool> use_hpf; 110 std::optional<bool> use_ns; 111 std::optional<int> use_ts; 112 std::optional<bool> use_analog_agc; 113 std::optional<bool> use_all; 114 std::optional<bool> analog_agc_use_digital_adaptive_controller; 115 std::optional<int> agc_mode; 116 std::optional<int> agc_target_level; 117 std::optional<bool> use_agc_limiter; 118 std::optional<int> agc_compression_gain; 119 std::optional<bool> agc2_use_adaptive_gain; 120 std::optional<float> agc2_fixed_gain_db; 121 std::optional<bool> agc2_use_input_volume_controller; 122 std::optional<float> pre_amplifier_gain_factor; 123 std::optional<float> pre_gain_factor; 124 std::optional<float> post_gain_factor; 125 std::optional<float> analog_mic_gain_emulation_initial_level; 126 std::optional<int> ns_level; 127 std::optional<bool> ns_analysis_on_linear_aec_output; 128 std::optional<bool> override_key_pressed; 129 std::optional<int> maximum_internal_processing_rate; 130 int initial_mic_level; 131 bool simulate_mic_gain = false; 132 std::optional<bool> multi_channel_render; 133 std::optional<bool> multi_channel_capture; 134 std::optional<int> simulated_mic_kind; 135 std::optional<int> frame_for_sending_capture_output_used_false; 136 std::optional<int> frame_for_sending_capture_output_used_true; 137 bool report_performance = false; 138 std::optional<std::string> performance_report_output_filename; 139 bool report_bitexactness = false; 140 bool use_verbose_logging = false; 141 bool use_quiet_output = false; 142 bool discard_all_settings_in_aecdump = true; 143 std::optional<std::string> aec_dump_input_filename; 144 std::optional<std::string> aec_dump_output_filename; 145 bool fixed_interface = false; 146 bool store_intermediate_output = false; 147 bool print_aec_parameter_values = false; 148 bool dump_internal_data = false; 149 WavFile::SampleFormat wav_output_format = WavFile::SampleFormat::kInt16; 150 std::optional<std::string> dump_internal_data_output_dir; 151 std::optional<int> dump_set_to_use; 152 std::optional<std::string> call_order_input_filename; 153 std::optional<std::string> call_order_output_filename; 154 std::optional<std::string> aec_settings_filename; 155 std::optional<absl::string_view> aec_dump_input_string; 156 std::vector<float>* processed_capture_samples = nullptr; 157 bool analysis_only = false; 158 std::optional<int> dump_start_frame; 159 std::optional<int> dump_end_frame; 160 std::optional<int> init_to_process; 161 std::optional<std::string> neural_echo_residual_estimator_model; 162 }; 163 164 // Provides common functionality for performing audioprocessing simulations. 165 class AudioProcessingSimulator { 166 public: 167 AudioProcessingSimulator( 168 const SimulationSettings& settings, 169 absl_nonnull scoped_refptr<AudioProcessing> audio_processing); 170 171 AudioProcessingSimulator() = delete; 172 AudioProcessingSimulator(const AudioProcessingSimulator&) = delete; 173 AudioProcessingSimulator& operator=(const AudioProcessingSimulator&) = delete; 174 175 virtual ~AudioProcessingSimulator(); 176 177 // Processes the data in the input. 178 virtual void Process() = 0; 179 180 // Returns the execution times of all AudioProcessing calls. 181 const ApiCallStatistics& GetApiCallStatistics() const { 182 return api_call_statistics_; 183 } 184 185 // Analyzes the data in the input and reports the resulting statistics. 186 virtual void Analyze() = 0; 187 188 // Reports whether the processed recording was bitexact. 189 bool OutputWasBitexact() { return bitexact_output_; } 190 191 size_t get_num_process_stream_calls() { return num_process_stream_calls_; } 192 size_t get_num_reverse_process_stream_calls() { 193 return num_reverse_process_stream_calls_; 194 } 195 196 protected: 197 void ProcessStream(bool fixed_interface); 198 void ProcessReverseStream(bool fixed_interface); 199 void ConfigureAudioProcessor(); 200 void DetachAecDump(); 201 void SetupBuffersConfigsOutputs(int input_sample_rate_hz, 202 int output_sample_rate_hz, 203 int reverse_input_sample_rate_hz, 204 int reverse_output_sample_rate_hz, 205 int input_num_channels, 206 int output_num_channels, 207 int reverse_input_num_channels, 208 int reverse_output_num_channels); 209 void SelectivelyToggleDataDumping(int init_index, 210 int capture_frames_since_init) const; 211 212 const SimulationSettings settings_; 213 scoped_refptr<AudioProcessing> ap_; 214 215 std::unique_ptr<ChannelBuffer<float>> in_buf_; 216 std::unique_ptr<ChannelBuffer<float>> out_buf_; 217 std::unique_ptr<ChannelBuffer<float>> reverse_in_buf_; 218 std::unique_ptr<ChannelBuffer<float>> reverse_out_buf_; 219 std::vector<std::array<float, 160>> linear_aec_output_buf_; 220 StreamConfig in_config_; 221 StreamConfig out_config_; 222 StreamConfig reverse_in_config_; 223 StreamConfig reverse_out_config_; 224 std::unique_ptr<ChannelBufferWavReader> buffer_reader_; 225 std::unique_ptr<ChannelBufferWavReader> reverse_buffer_reader_; 226 Int16Frame rev_frame_; 227 Int16Frame fwd_frame_; 228 bool bitexact_output_ = true; 229 std::optional<int> aec_dump_applied_input_level_ = 0; 230 231 protected: 232 size_t output_reset_counter_ = 0; 233 234 private: 235 void SetupOutput(); 236 237 size_t num_process_stream_calls_ = 0; 238 size_t num_reverse_process_stream_calls_ = 0; 239 std::unique_ptr<ChannelBufferWavWriter> buffer_file_writer_; 240 std::unique_ptr<ChannelBufferWavWriter> reverse_buffer_file_writer_; 241 std::unique_ptr<ChannelBufferVectorWriter> buffer_memory_writer_; 242 std::unique_ptr<WavWriter> linear_aec_output_file_writer_; 243 ApiCallStatistics api_call_statistics_; 244 std::ofstream residual_echo_likelihood_graph_writer_; 245 int applied_input_volume_; 246 FakeRecordingDevice fake_recording_device_; 247 248 TaskQueueForTest worker_queue_; 249 }; 250 251 } // namespace test 252 } // namespace webrtc 253 254 #endif // MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_SIMULATOR_H_