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

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 config.Set<ExtendedFilter>(new ExtendedFilter(
226 !settings_.use_extended_filter || *settings_.use_extended_filter));
227 config.Set<DelayAgnostic>(new DelayAgnostic(!settings_.use_delay_agnostic ||
228 *settings_.use_delay_agnostic));
229
230 ap_.reset(AudioProcessing::Create(config));
231
232 if (settings_.use_aec) {
233 RTC_CHECK_EQ(AudioProcessing::kNoError,
234 ap_->echo_cancellation()->Enable(*settings_.use_aec));
235 }
236 if (settings_.use_aecm) {
237 RTC_CHECK_EQ(AudioProcessing::kNoError,
238 ap_->echo_control_mobile()->Enable(*settings_.use_aecm));
239 }
240 if (settings_.use_agc) {
241 RTC_CHECK_EQ(AudioProcessing::kNoError,
242 ap_->gain_control()->Enable(*settings_.use_agc));
243 }
244 if (settings_.use_hpf) {
245 RTC_CHECK_EQ(AudioProcessing::kNoError,
246 ap_->high_pass_filter()->Enable(*settings_.use_hpf));
247 }
248 if (settings_.use_ns) {
249 RTC_CHECK_EQ(AudioProcessing::kNoError,
250 ap_->noise_suppression()->Enable(*settings_.use_ns));
251 }
252 if (settings_.use_le) {
253 RTC_CHECK_EQ(AudioProcessing::kNoError,
254 ap_->level_estimator()->Enable(*settings_.use_le));
255 }
256 if (settings_.use_vad) {
257 RTC_CHECK_EQ(AudioProcessing::kNoError,
258 ap_->voice_detection()->Enable(*settings_.use_vad));
259 }
260 if (settings_.use_agc_limiter) {
261 RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->gain_control()->enable_limiter(
262 *settings_.use_agc_limiter));
263 }
264 if (settings_.agc_target_level) {
265 RTC_CHECK_EQ(AudioProcessing::kNoError,
266 ap_->gain_control()->set_target_level_dbfs(
267 *settings_.agc_target_level));
268 }
269
270 if (settings_.agc_mode) {
271 RTC_CHECK_EQ(
272 AudioProcessing::kNoError,
273 ap_->gain_control()->set_mode(
274 static_cast<webrtc::GainControl::Mode>(*settings_.agc_mode)));
275 }
276
277 if (settings_.use_drift_compensation) {
278 RTC_CHECK_EQ(AudioProcessing::kNoError,
279 ap_->echo_cancellation()->enable_drift_compensation(
280 *settings_.use_drift_compensation));
281 }
282
283 if (settings_.aec_suppression_level) {
284 RTC_CHECK_EQ(AudioProcessing::kNoError,
285 ap_->echo_cancellation()->set_suppression_level(
286 static_cast<webrtc::EchoCancellation::SuppressionLevel>(
287 *settings_.aec_suppression_level)));
288 }
289
290 if (settings_.aecm_routing_mode) {
291 RTC_CHECK_EQ(AudioProcessing::kNoError,
292 ap_->echo_control_mobile()->set_routing_mode(
293 static_cast<webrtc::EchoControlMobile::RoutingMode>(
294 *settings_.aecm_routing_mode)));
295 }
296
297 if (settings_.use_aecm_comfort_noise) {
298 RTC_CHECK_EQ(AudioProcessing::kNoError,
299 ap_->echo_control_mobile()->enable_comfort_noise(
300 *settings_.use_aecm_comfort_noise));
301 }
302
303 if (settings_.vad_likelihood) {
304 RTC_CHECK_EQ(AudioProcessing::kNoError,
305 ap_->voice_detection()->set_likelihood(
306 static_cast<webrtc::VoiceDetection::Likelihood>(
307 *settings_.vad_likelihood)));
308 }
309 if (settings_.ns_level) {
310 RTC_CHECK_EQ(
311 AudioProcessing::kNoError,
312 ap_->noise_suppression()->set_level(
313 static_cast<NoiseSuppression::Level>(*settings_.ns_level)));
314 }
315
316 if (settings_.use_ts) {
317 ap_->set_stream_key_pressed(*settings_.use_ts);
318 }
319
320 if (settings_.aec_dump_output_filename) {
321 size_t kMaxFilenameSize = AudioProcessing::kMaxFilenameSize;
322 RTC_CHECK_LE(settings_.aec_dump_output_filename->size(), kMaxFilenameSize);
323 RTC_CHECK_EQ(AudioProcessing::kNoError,
324 ap_->StartDebugRecording(
325 settings_.aec_dump_output_filename->c_str(), -1));
326 }
327 }
328
329 } // namespace test
330 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698