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

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

Powered by Google App Engine
This is Rietveld 408576698