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

Side by Side 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, 7 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 unified diff | Download patch
OLDNEW
(Empty)
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 #include "webrtc/modules/audio_processing/test/audio_processing_simulator.h"
12
13 #include <algorithm>
14 #include <sstream>
15 #include <string>
16 #include <vector>
17
18 #include "webrtc/base/stringutils.h"
19 #include "webrtc/common_audio/include/audio_util.h"
20 #include "webrtc/modules/audio_processing/include/audio_processing.h"
21
22 namespace webrtc {
23 namespace test {
24 namespace {
25
26 void CopyFromAudioFrame(const AudioFrame& src, ChannelBuffer<float>* dest) {
27 RTC_CHECK_EQ(src.num_channels_, dest->num_channels());
28 RTC_CHECK_EQ(src.samples_per_channel_, dest->num_frames());
29 // Copy the data from the input buffer.
30 std::vector<float> tmp(src.samples_per_channel_ * src.num_channels_);
31 S16ToFloat(src.data_, tmp.size(), tmp.data());
32 Deinterleave(tmp.data(), src.samples_per_channel_, src.num_channels_,
33 dest->channels());
34 }
35
36 std::string GetIndexedOutputWavFilename(const std::string& wav_name,
37 int counter) {
38 std::stringstream ss;
39 ss << wav_name.substr(0, wav_name.size() - 4) << "_" << counter
40 << wav_name.substr(wav_name.size() - 4);
41 return ss.str();
42 }
43
44 } // namespace
45
46 void CopyToAudioFrame(const ChannelBuffer<float>& src, AudioFrame* dest) {
47 RTC_CHECK_EQ(src.num_channels(), dest->num_channels_);
48 RTC_CHECK_EQ(src.num_frames(), dest->samples_per_channel_);
49 for (size_t ch = 0; ch < dest->num_channels_; ++ch) {
50 for (size_t sample = 0; sample < dest->samples_per_channel_; ++sample) {
51 dest->data_[sample * dest->num_channels_ + ch] =
52 src.channels()[ch][sample] * 32767;
53 }
54 }
55 }
56
57 AudioProcessingSimulator::ScopedTimer::~ScopedTimer() {
58 TickInterval interval = TickTime::Now() - start_time_;
59 proc_time_->sum += interval;
60 proc_time_->max = std::max(proc_time_->max, interval);
61 proc_time_->min = std::min(proc_time_->min, interval);
62 }
63
64 void AudioProcessingSimulator::ProcessStream(bool fixed_interface) {
65 if (fixed_interface) {
66 {
67 const auto st = ScopedTimer(mutable_proc_time());
68 RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->ProcessStream(&fwd_frame_));
69 }
70 CopyFromAudioFrame(fwd_frame_, out_buf_.get());
71 } else {
72 const auto st = ScopedTimer(mutable_proc_time());
73 RTC_CHECK_EQ(AudioProcessing::kNoError,
74 ap_->ProcessStream(in_buf_->channels(), in_config_,
75 out_config_, out_buf_->channels()));
76 }
77
78 if (buffer_writer_) {
79 buffer_writer_->Write(*out_buf_);
80 }
81
82 ++num_process_stream_calls_;
83 }
84
85 void AudioProcessingSimulator::ProcessReverseStream(bool fixed_interface) {
86 if (fixed_interface) {
87 const auto st = ScopedTimer(mutable_proc_time());
88 RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->ProcessStream(&rev_frame_));
89 CopyFromAudioFrame(rev_frame_, reverse_out_buf_.get());
90
91 } else {
92 const auto st = ScopedTimer(mutable_proc_time());
93 RTC_CHECK_EQ(AudioProcessing::kNoError,
94 ap_->ProcessReverseStream(
95 reverse_in_buf_->channels(), reverse_in_config_,
96 reverse_out_config_, reverse_out_buf_->channels()));
97 }
98
99 if (reverse_buffer_writer_) {
100 reverse_buffer_writer_->Write(*reverse_out_buf_);
101 }
102
103 ++num_reverse_process_stream_calls_;
104 }
105
106 void AudioProcessingSimulator::SetupBuffersConfigsOutputs(
107 int input_sample_rate_hz,
108 int output_sample_rate_hz,
109 int reverse_input_sample_rate_hz,
110 int reverse_output_sample_rate_hz,
111 int input_num_channels,
112 int output_num_channels,
113 int reverse_input_num_channels,
114 int reverse_output_num_channels) {
115 in_config_ = StreamConfig(input_sample_rate_hz, input_num_channels);
116 in_buf_.reset(new ChannelBuffer<float>(
117 rtc::CheckedDivExact(input_sample_rate_hz, kChunksPerSecond),
118 input_num_channels));
119
120 reverse_in_config_ =
121 StreamConfig(reverse_input_sample_rate_hz, reverse_input_num_channels);
122 reverse_in_buf_.reset(new ChannelBuffer<float>(
123 rtc::CheckedDivExact(reverse_input_sample_rate_hz, kChunksPerSecond),
124 reverse_input_num_channels));
125
126 out_config_ = StreamConfig(output_sample_rate_hz, output_num_channels);
127 out_buf_.reset(new ChannelBuffer<float>(
128 rtc::CheckedDivExact(output_sample_rate_hz, kChunksPerSecond),
129 output_num_channels));
130
131 reverse_out_config_ =
132 StreamConfig(reverse_output_sample_rate_hz, reverse_output_num_channels);
133 reverse_out_buf_.reset(new ChannelBuffer<float>(
134 rtc::CheckedDivExact(reverse_output_sample_rate_hz, kChunksPerSecond),
135 reverse_output_num_channels));
136
137 fwd_frame_.sample_rate_hz_ = input_sample_rate_hz;
138 fwd_frame_.samples_per_channel_ =
139 rtc::CheckedDivExact(fwd_frame_.sample_rate_hz_, kChunksPerSecond);
140 fwd_frame_.num_channels_ = input_num_channels;
141
142 rev_frame_.sample_rate_hz_ = reverse_input_sample_rate_hz;
143 rev_frame_.samples_per_channel_ =
144 rtc::CheckedDivExact(rev_frame_.sample_rate_hz_, kChunksPerSecond);
145 rev_frame_.num_channels_ = reverse_input_num_channels;
146
147 if (settings_.use_verbose_logging) {
148 printf("Sample rates:\n");
149 printf(" Forward input: %d\n", input_sample_rate_hz);
150 printf(" Forward output: %d\n", output_sample_rate_hz);
151 printf(" Reverse input: %d\n", reverse_input_sample_rate_hz);
152 printf(" Reverse output: %d\n", reverse_output_sample_rate_hz);
153 printf("Number of channels:\n");
154 printf(" Forward input: %d\n", input_num_channels);
155 printf(" Forward output: %d\n", output_num_channels);
156 printf(" Reverse input: %d\n", reverse_input_num_channels);
157 printf(" Reverse output: %d\n", reverse_output_num_channels);
158 }
159
160 SetupOutput();
161 }
162
163 void AudioProcessingSimulator::SetupOutput() {
164 if (settings_.output_filename) {
165 std::string filename;
166 if (settings_.store_intermediate_output) {
167 filename = GetIndexedOutputWavFilename(*settings_.output_filename,
168 output_reset_counter_);
169 } else {
170 filename = *settings_.output_filename;
171 }
172
173 std::unique_ptr<WavWriter> out_file(
174 new WavWriter(filename, out_config_.sample_rate_hz(),
175 static_cast<size_t>(out_config_.num_channels())));
176 buffer_writer_.reset(new ChannelBufferWavWriter(std::move(out_file)));
177 }
178
179 if (settings_.reverse_output_filename) {
180 std::string filename;
181 if (settings_.store_intermediate_output) {
182 filename = GetIndexedOutputWavFilename(*settings_.reverse_output_filename,
183 output_reset_counter_);
184 } else {
185 filename = *settings_.reverse_output_filename;
186 }
187
188 std::unique_ptr<WavWriter> reverse_out_file(
189 new WavWriter(filename, reverse_out_config_.sample_rate_hz(),
190 static_cast<size_t>(reverse_out_config_.num_channels())));
191 reverse_buffer_writer_.reset(
192 new ChannelBufferWavWriter(std::move(reverse_out_file)));
193 }
194
195 ++output_reset_counter_;
196 }
197
198 void AudioProcessingSimulator::DestroyAudioProcessor() {
199 if (settings_.aec_dump_output_filename) {
200 RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->StopDebugRecording());
201 }
202 }
203
204 void AudioProcessingSimulator::CreateAudioProcessor() {
205 Config config;
206 if (settings_.use_bf && *settings_.use_bf) {
207 config.Set<Beamforming>(new Beamforming(
208 true, ParseArrayGeometry(*settings_.microphone_positions),
209 SphericalPointf(DegreesToRadians(settings_.target_angle_degrees), 0.f,
210 1.f)));
211 }
212 if (settings_.use_ts) {
213 config.Set<ExperimentalNs>(new ExperimentalNs(*settings_.use_ts));
214 }
215 if (settings_.use_ie) {
216 config.Set<Intelligibility>(new Intelligibility(*settings_.use_ie));
217 }
218 if (settings_.use_aec3) {
219 config.Set<EchoCanceller3>(new EchoCanceller3(*settings_.use_aec3));
220 }
221 if (settings_.use_refined_adaptive_filter) {
222 config.Set<RefinedAdaptiveFilter>(
223 new RefinedAdaptiveFilter(*settings_.use_refined_adaptive_filter));
224 }
225 if (settings_.use_extended_filter && !(*settings_.use_extended_filter)) {
226 config.Set<ExtendedFilter>(new ExtendedFilter(false));
227 } else {
228 config.Set<ExtendedFilter>(new ExtendedFilter(true));
229 }
230 if (settings_.use_delay_agnostic && !(*settings_.use_delay_agnostic)) {
231 config.Set<DelayAgnostic>(new DelayAgnostic(false));
232 } else {
233 config.Set<DelayAgnostic>(new DelayAgnostic(true));
234 }
235
236 ap_.reset(AudioProcessing::Create(config));
237
238 if (settings_.use_aec) {
239 RTC_CHECK_EQ(AudioProcessing::kNoError,
240 ap_->echo_cancellation()->Enable(*settings_.use_aec));
241 }
242 if (settings_.use_aecm) {
243 RTC_CHECK_EQ(AudioProcessing::kNoError,
244 ap_->echo_control_mobile()->Enable(*settings_.use_aecm));
245 }
246 if (settings_.use_agc) {
247 RTC_CHECK_EQ(AudioProcessing::kNoError,
248 ap_->gain_control()->Enable(*settings_.use_agc));
249 }
250 if (settings_.use_hpf) {
251 RTC_CHECK_EQ(AudioProcessing::kNoError,
252 ap_->high_pass_filter()->Enable(*settings_.use_hpf));
253 }
254 if (settings_.use_ns) {
255 RTC_CHECK_EQ(AudioProcessing::kNoError,
256 ap_->noise_suppression()->Enable(*settings_.use_ns));
257 }
258 if (settings_.use_le) {
259 RTC_CHECK_EQ(AudioProcessing::kNoError,
260 ap_->level_estimator()->Enable(*settings_.use_le));
261 }
262 if (settings_.use_vad) {
263 RTC_CHECK_EQ(AudioProcessing::kNoError,
264 ap_->voice_detection()->Enable(*settings_.use_vad));
265 }
266 if (settings_.use_agc_limiter) {
267 RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->gain_control()->enable_limiter(
268 *settings_.use_agc_limiter));
269 }
270 if (settings_.agc_target_level) {
271 RTC_CHECK_EQ(AudioProcessing::kNoError,
272 ap_->gain_control()->set_target_level_dbfs(
273 *settings_.agc_target_level));
274 }
275
276 if (settings_.agc_mode) {
277 RTC_CHECK_EQ(
278 AudioProcessing::kNoError,
279 ap_->gain_control()->set_mode(
280 static_cast<webrtc::GainControl::Mode>(*settings_.agc_mode)));
281 }
282
283 if (settings_.use_drift_compensation) {
284 RTC_CHECK_EQ(AudioProcessing::kNoError,
285 ap_->echo_cancellation()->enable_drift_compensation(
286 *settings_.use_drift_compensation));
287 }
288
289 if (settings_.aec_suppression_level) {
290 RTC_CHECK_EQ(AudioProcessing::kNoError,
291 ap_->echo_cancellation()->set_suppression_level(
292 static_cast<webrtc::EchoCancellation::SuppressionLevel>(
293 *settings_.aec_suppression_level)));
294 }
295
296 if (settings_.aecm_routing_mode) {
297 RTC_CHECK_EQ(AudioProcessing::kNoError,
298 ap_->echo_control_mobile()->set_routing_mode(
299 static_cast<webrtc::EchoControlMobile::RoutingMode>(
300 *settings_.aecm_routing_mode)));
301 }
302
303 if (settings_.use_aecm_comfort_noise) {
304 RTC_CHECK_EQ(AudioProcessing::kNoError,
305 ap_->echo_control_mobile()->enable_comfort_noise(
306 *settings_.use_aecm_comfort_noise));
307 }
308
309 if (settings_.vad_likelihood) {
310 RTC_CHECK_EQ(AudioProcessing::kNoError,
311 ap_->voice_detection()->set_likelihood(
312 static_cast<webrtc::VoiceDetection::Likelihood>(
313 *settings_.vad_likelihood)));
314 }
315 if (settings_.ns_level) {
316 RTC_CHECK_EQ(
317 AudioProcessing::kNoError,
318 ap_->noise_suppression()->set_level(
319 static_cast<NoiseSuppression::Level>(*settings_.ns_level)));
320 }
321
322 if (settings_.use_ts) {
323 ap_->set_stream_key_pressed(*settings_.use_ts);
324 }
325
326 if (settings_.aec_dump_output_filename) {
327 size_t kMaxFilenameSize = AudioProcessing::kMaxFilenameSize;
328 RTC_CHECK_LE(settings_.aec_dump_output_filename->size(), kMaxFilenameSize);
329 RTC_CHECK_EQ(AudioProcessing::kNoError,
330 ap_->StartDebugRecording(
331 settings_.aec_dump_output_filename->c_str(), -1));
332 }
333 }
334
335 } // namespace test
336 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698