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

Side by Side Diff: webrtc/modules/audio_processing/test/audioproc_float.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: Fixed the bitexactness check when operating on aecdump data 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
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
aluebs-webrtc 2016/04/26 04:33:39 I don't think the year should be updated because o
peah-webrtc 2016/04/26 07:19:29 Done.
aluebs-webrtc 2016/04/27 16:06:47 It was 2014 though.
peah-webrtc 2016/04/28 07:41:11 Sorry. Done.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <stdio.h>
12
13 #include <iostream>
14 #include <memory> 11 #include <memory>
15 #include <sstream>
16 #include <string>
17 #include <utility>
18 12
19 #include "gflags/gflags.h" 13 #include "gflags/gflags.h"
20 #include "webrtc/base/checks.h"
21 #include "webrtc/base/format_macros.h"
22 #include "webrtc/common_audio/channel_buffer.h"
23 #include "webrtc/common_audio/wav_file.h"
24 #include "webrtc/modules/audio_processing/include/audio_processing.h" 14 #include "webrtc/modules/audio_processing/include/audio_processing.h"
25 #include "webrtc/modules/audio_processing/test/audio_file_processor.h" 15 #include "webrtc/modules/audio_processing/test/aec_dump_based_simulator.h"
26 #include "webrtc/modules/audio_processing/test/protobuf_utils.h" 16 #include "webrtc/modules/audio_processing/test/audio_processing_simulator.h"
27 #include "webrtc/modules/audio_processing/test/test_utils.h" 17 #include "webrtc/modules/audio_processing/test/wav_based_simulator.h"
28 #include "webrtc/system_wrappers/include/tick_util.h" 18
29 #include "webrtc/test/testsupport/trace_to_stderr.h" 19 namespace webrtc {
30 20 namespace test {
31 namespace { 21 namespace {
32 22
33 bool ValidateOutChannels(const char* flagname, int32_t value) { 23 const int kParameterNotSpecifiedValue = -10000;
34 return value >= 0; 24
25 const char kUsageDescription[] =
26 "Usage: audioproc_f [options] -i <input.wav>\n"
27 " or\n"
28 " audioproc_f [options] -dump <aec_dump>\n"
29 "\n\n"
30 "Command-line tool to simulate a call using the audio "
31 "processing module, either based on wav files or "
32 "protobuf debug dump recordings and writes to an output";
33
34 DEFINE_string(dump_input, "", "Aec dump input filename");
35 DEFINE_string(dump_output, "", "Aec dump output filename");
36 DEFINE_string(i, "", "Forward stream input wav filename");
37 DEFINE_string(o, "", "Forward stream output wav filename");
aluebs-webrtc 2016/04/26 04:33:39 Don't we ant some default value for the output fil
peah-webrtc 2016/04/26 07:19:29 I don't think so. In many cases the output is not
aluebs-webrtc 2016/04/27 16:06:47 I think in most of the cases the output is of inte
peah-webrtc 2016/04/28 07:41:11 Acknowledged.
38 DEFINE_string(ri, "", "Reverse stream input wav filename");
39 DEFINE_string(ro, "", "Reverse stream output wav filename");
40 DEFINE_int32(num_output_channels,
41 kParameterNotSpecifiedValue,
42 "Number of forward stream output channels (1-2)");
aluebs-webrtc 2016/04/26 04:33:39 Any number of channels is supported, right?
peah-webrtc 2016/04/26 07:19:29 I'll change that to support any channels. Done.
43 DEFINE_int32(num_reverse_output_channels,
44 kParameterNotSpecifiedValue,
45 "Number of Reverse stream output channels (1-2)");
46 DEFINE_int32(output_sample_rate_hz,
47 kParameterNotSpecifiedValue,
48 "Forward stream output sample rate in Hz (1-48000)");
49 DEFINE_int32(reverse_output_sample_rate_hz,
50 kParameterNotSpecifiedValue,
51 "Reverse stream output sample rate in Hz (1-48000)");
52 DEFINE_string(mic_positions,
53 "",
54 "Space delimited cartesian coordinates of microphones in "
55 "meters. The coordinates of each point are contiguous. For a "
56 "two element array: \"x1 y1 z1 x2 y2 z2\"");
57 DEFINE_int32(target_angle_degrees,
58 90,
59 "The azimuth of the target in degrees (0-90). Only applies to "
60 "beamforming.");
61 DEFINE_bool(fixed_interface,
62 false,
63 "Use the fixed interface when operating on wav files");
64 DEFINE_bool(aec, false, "Activate the canceller");
aluebs-webrtc 2016/04/26 04:33:39 echo canceller?
peah-webrtc 2016/04/26 07:19:29 Done.
65 DEFINE_bool(no_aec, false, "Dectivate the echo canceller");
66 DEFINE_bool(aecm, false, "Activate the mobile echo controller");
67 DEFINE_bool(no_aecm, false, "Dectivate the mobile echo controller");
68 DEFINE_bool(agc, false, "Activate the AGC");
69 DEFINE_bool(no_agc, false, "Dectivate the AGC");
70 DEFINE_bool(hpf, false, "Activate the high-pass filter");
71 DEFINE_bool(no_hpf, false, "Dectivate the high-pass filter");
72 DEFINE_bool(ns, false, "Activate the noise suppressor");
73 DEFINE_bool(no_ns, false, "Dectivate the noise suppressor");
74 DEFINE_bool(ts, false, "Activate the transient suppressor");
75 DEFINE_bool(no_ts, false, "Dectivate the transient suppressor");
76 DEFINE_bool(bf, false, "Activate the beamformer");
77 DEFINE_bool(no_bf, false, "Dectivate the beamformer");
78 DEFINE_bool(ie, false, "Activate the intelligibility enhancer");
79 DEFINE_bool(no_ie, false, "Dectivate the intelligibility enhancer");
80 DEFINE_bool(vad, false, "Activate the voice activity detector");
81 DEFINE_bool(no_vad, false, "Dectivate the voice activity detector");
82 DEFINE_bool(le, false, "Activate the level estimator");
83 DEFINE_bool(no_le, false, "Dectivate the level estimator");
aluebs-webrtc 2016/04/26 04:33:39 Why do we need 2 flags to specify if a component i
peah-webrtc 2016/04/26 07:19:29 This was the most simple way (for the user of the
aluebs-webrtc 2016/04/27 16:06:47 I personally prefer 1 int flag than 2 different bo
peah-webrtc 2016/04/28 07:41:11 That sounds like a good option. But I see the draw
aluebs-webrtc 2016/04/30 02:08:04 I prefer the global flag suggestion, but I am open
peah-webrtc 2016/05/02 06:18:42 Maybe I misunderstood you but my concern is what I
aluebs-webrtc 2016/05/03 22:30:40 I see the point when you want to use the aecdump v
peah-webrtc 2016/05/09 11:37:30 Acknowledged.
84 DEFINE_bool(all_default,
85 false,
86 "Activate all of the default components (will be overridden by any "
87 "other settings)");
88 DEFINE_int32(aec_suppression_level,
89 kParameterNotSpecifiedValue,
90 "Set the aec suppression level (0-2)");
91 DEFINE_bool(delay_agnostic, false, "Activate the level estimator");
92 DEFINE_bool(no_delay_agnostic, false, "Dectivate the level estimator");
93 DEFINE_bool(extended_filter, false, "Activate the level estimator");
94 DEFINE_bool(no_extended_filter, false, "Dectivate the level estimator");
95 DEFINE_bool(drift_compensation, false, "Activate the level estimator");
96 DEFINE_bool(no_drift_compensation, false, "Dectivate the level estimator");
97 DEFINE_bool(aec3, false, "Activate the level estimator");
98 DEFINE_bool(no_aec3, false, "Dectivate the level estimator");
99 DEFINE_bool(refined_adaptive_filter,
100 false,
101 "Activate the refined adaptive filter functionality");
102 DEFINE_bool(no_refined_adaptive_filter,
103 false,
104 "Deactivate the refined adaptive filter functionality");
105 DEFINE_int32(aecm_routing_mode,
106 kParameterNotSpecifiedValue,
107 "Specify the AECM routing mode (0-4)");
108 DEFINE_bool(aecm_comfort_noise, false, "Activate the AECM comfort noise");
109 DEFINE_bool(no_aecm_comfort_noise, false, "Dectivate the AECM comfort noise");
110 DEFINE_int32(agc_mode,
111 kParameterNotSpecifiedValue,
112 "Specify the AGC mode (0-2)");
113 DEFINE_int32(agc_target_level,
114 kParameterNotSpecifiedValue,
115 "Specify the AGC target level (0-31)");
116 DEFINE_bool(agc_limiter, false, "Activate the level estimator");
117 DEFINE_bool(no_agc_limiter, false, "Dectivate the level estimator");
118 DEFINE_int32(agc_compression_gain,
119 kParameterNotSpecifiedValue,
120 "Specify the AGC compression gain (0-90)");
121 DEFINE_int32(vad_likelihood,
122 kParameterNotSpecifiedValue,
123 "Specify the VAD likelihood (0-3)");
124 DEFINE_int32(ns_level,
125 kParameterNotSpecifiedValue,
126 "Specify the NS level (0-3)");
127 DEFINE_int32(stream_delay,
128 kParameterNotSpecifiedValue,
129 "Specify the stream delay in ms to use");
130 DEFINE_int32(stream_drift_samples,
131 kParameterNotSpecifiedValue,
132 "Specify the number of stream drift samples to use");
133 DEFINE_bool(performance_report, false, "Report the APM performance ");
134 DEFINE_bool(verbose, false, "Produce verbose output");
135 DEFINE_bool(bitexactness_report,
136 false,
137 "Report bitexactness for aec dump result reproduction");
138 DEFINE_bool(discard_settings_in_aecdump,
aluebs-webrtc 2016/04/26 04:33:39 Probably more intuitive to use the positive opposi
peah-webrtc 2016/04/26 07:19:29 The absolutely most common thing to do when analyz
aluebs-webrtc 2016/04/27 16:06:47 Yes, you just --use nouse_aecdump_settings
peah-webrtc 2016/04/28 07:41:11 Yes, but that would then mean that "use_aecdump_se
aluebs-webrtc 2016/04/30 02:08:04 Agreed. Let's leave it as is.
peah-webrtc 2016/05/09 11:37:30 Acknowledged.
139 false,
140 "Discard any config settings specified in the aec dump");
141 DEFINE_bool(store_intermediate_output,
142 false,
143 "Creates new output files after each init");
144
145 void SetSettingIfSpecified(const std::string value,
146 rtc::Optional<std::string>* parameter) {
147 if (value.compare("") != 0) {
148 *parameter = rtc::Optional<std::string>(value);
149 }
150 }
151
152 void SetSettingIfSpecified(int value, rtc::Optional<int>* parameter) {
153 if (value != kParameterNotSpecifiedValue) {
154 *parameter = rtc::Optional<int>(value);
155 }
156 }
157
158 void SetSettingIfFlagSet(bool condition,
159 rtc::Optional<bool>* parameter,
160 bool value_to_set) {
161 if (condition) {
162 *parameter = rtc::Optional<bool>(value_to_set);
163 }
164 }
165
166 SimulationSettings CreateSettings() {
167 SimulationSettings settings;
168 if (FLAGS_all_default) {
169 settings.use_le = rtc::Optional<bool>(true);
170 settings.use_vad = rtc::Optional<bool>(true);
171 settings.use_ie = rtc::Optional<bool>(false);
172 settings.use_bf = rtc::Optional<bool>(false);
173 settings.use_ts = rtc::Optional<bool>(true);
174 settings.use_ns = rtc::Optional<bool>(true);
175 settings.use_hpf = rtc::Optional<bool>(true);
176 settings.use_agc = rtc::Optional<bool>(true);
177 settings.use_aec = rtc::Optional<bool>(true);
178 settings.use_aecm = rtc::Optional<bool>(false);
179 }
180 SetSettingIfSpecified(FLAGS_dump_input, &settings.aec_dump_input_filename);
181 SetSettingIfSpecified(FLAGS_dump_output, &settings.aec_dump_output_filename);
182 SetSettingIfSpecified(FLAGS_i, &settings.input_filename);
183 SetSettingIfSpecified(FLAGS_o, &settings.output_filename);
184 SetSettingIfSpecified(FLAGS_ri, &settings.reverse_input_filename);
185 SetSettingIfSpecified(FLAGS_ro, &settings.reverse_output_filename);
186 SetSettingIfSpecified(FLAGS_num_output_channels,
187 &settings.output_num_channels);
188 SetSettingIfSpecified(FLAGS_num_reverse_output_channels,
189 &settings.reverse_output_num_channels);
aluebs-webrtc 2016/04/26 04:33:39 For these parameters it would be great to ave the
peah-webrtc 2016/04/26 07:19:29 Good point! Done.
190 SetSettingIfSpecified(FLAGS_output_sample_rate_hz,
191 &settings.output_sample_rate_hz);
192 SetSettingIfSpecified(FLAGS_reverse_output_sample_rate_hz,
193 &settings.reverse_output_sample_rate_hz);
194 SetSettingIfSpecified(FLAGS_mic_positions, &settings.microphone_positions);
195 settings.target_angle_degrees = FLAGS_target_angle_degrees;
196 SetSettingIfFlagSet(FLAGS_aec, &settings.use_aec, true);
197 SetSettingIfFlagSet(FLAGS_no_aec, &settings.use_aec, false);
198 SetSettingIfFlagSet(FLAGS_aecm, &settings.use_aecm, true);
199 SetSettingIfFlagSet(FLAGS_no_aecm, &settings.use_aecm, false);
200 SetSettingIfFlagSet(FLAGS_agc, &settings.use_agc, true);
201 SetSettingIfFlagSet(FLAGS_no_agc, &settings.use_agc, false);
202 SetSettingIfFlagSet(FLAGS_hpf, &settings.use_hpf, true);
203 SetSettingIfFlagSet(FLAGS_no_hpf, &settings.use_hpf, false);
204 SetSettingIfFlagSet(FLAGS_ns, &settings.use_ns, true);
205 SetSettingIfFlagSet(FLAGS_no_ns, &settings.use_ns, false);
206 SetSettingIfFlagSet(FLAGS_ts, &settings.use_ts, true);
207 SetSettingIfFlagSet(FLAGS_no_ts, &settings.use_ts, false);
208 SetSettingIfFlagSet(FLAGS_bf, &settings.use_bf, true);
209 SetSettingIfFlagSet(FLAGS_no_bf, &settings.use_bf, false);
210 SetSettingIfFlagSet(FLAGS_ie, &settings.use_ie, true);
211 SetSettingIfFlagSet(FLAGS_no_ie, &settings.use_ie, false);
212 SetSettingIfFlagSet(FLAGS_vad, &settings.use_vad, true);
213 SetSettingIfFlagSet(FLAGS_no_vad, &settings.use_vad, false);
214 SetSettingIfFlagSet(FLAGS_le, &settings.use_le, true);
215 SetSettingIfFlagSet(FLAGS_no_le, &settings.use_le, false);
aluebs-webrtc 2016/04/26 04:33:39 This can be simplified so much with my suggestion
peah-webrtc 2016/04/26 07:19:29 Yes, probably. But please explain more on how that
aluebs-webrtc 2016/04/27 16:06:46 See above.
peah-webrtc 2016/04/28 07:41:11 Acknowledged.
216 SetSettingIfSpecified(FLAGS_aec_suppression_level,
217 &settings.aec_suppression_level);
218 SetSettingIfFlagSet(FLAGS_delay_agnostic, &settings.use_delay_agnostic, true);
219 SetSettingIfFlagSet(FLAGS_no_delay_agnostic, &settings.use_delay_agnostic,
220 false);
221 SetSettingIfFlagSet(FLAGS_extended_filter, &settings.use_extended_filter,
222 true);
223 SetSettingIfFlagSet(FLAGS_no_extended_filter, &settings.use_extended_filter,
224 false);
225 SetSettingIfFlagSet(FLAGS_drift_compensation,
226 &settings.use_drift_compensation, true);
227 SetSettingIfFlagSet(FLAGS_no_drift_compensation,
228 &settings.use_drift_compensation, false);
229 SetSettingIfFlagSet(FLAGS_refined_adaptive_filter,
230 &settings.use_refined_adaptive_filter, true);
231 SetSettingIfFlagSet(FLAGS_no_refined_adaptive_filter,
232 &settings.use_refined_adaptive_filter, false);
233
234 SetSettingIfFlagSet(FLAGS_aec3, &settings.use_aec3, true);
235 SetSettingIfFlagSet(FLAGS_no_aec3, &settings.use_aec3, false);
236 SetSettingIfSpecified(FLAGS_aecm_routing_mode, &settings.aecm_routing_mode);
237 SetSettingIfFlagSet(FLAGS_aecm_comfort_noise,
238 &settings.use_aecm_comfort_noise, true);
239 SetSettingIfFlagSet(FLAGS_no_aecm_comfort_noise,
240 &settings.use_aecm_comfort_noise, false);
241 SetSettingIfSpecified(FLAGS_agc_mode, &settings.agc_mode);
242 SetSettingIfSpecified(FLAGS_agc_target_level, &settings.agc_target_level);
243 SetSettingIfFlagSet(FLAGS_agc_limiter, &settings.use_agc_limiter, true);
244 SetSettingIfFlagSet(FLAGS_no_agc_limiter, &settings.use_agc_limiter, false);
245 SetSettingIfSpecified(FLAGS_agc_compression_gain,
246 &settings.agc_compression_gain);
247 SetSettingIfSpecified(FLAGS_vad_likelihood, &settings.vad_likelihood);
248 SetSettingIfSpecified(FLAGS_ns_level, &settings.ns_level);
249 SetSettingIfSpecified(FLAGS_stream_delay, &settings.stream_delay);
250 SetSettingIfSpecified(FLAGS_stream_drift_samples,
251 &settings.stream_drift_samples);
252 settings.report_performance = FLAGS_performance_report;
253 settings.use_verbose_logging = FLAGS_verbose;
254 settings.report_bitexactness = FLAGS_bitexactness_report;
255 settings.discard_all_settings_in_aecdump = FLAGS_discard_settings_in_aecdump;
256 settings.fixed_interface = FLAGS_fixed_interface;
257 settings.store_intermediate_output = FLAGS_store_intermediate_output;
258
259 return settings;
260 }
261
262 void PerformBasicParameterSanityChecks(const SimulationSettings& settings) {
263 auto report_conditional_error_and_exit = [](bool condition,
aluebs-webrtc 2016/04/26 04:33:39 Why not making this a function directly?
peah-webrtc 2016/04/26 07:19:29 Done.
264 std::string message) {
265 if (condition) {
266 fprintf(stderr, "%s", message.c_str());
267 exit(1);
268 }
269 };
270
271 if (settings.input_filename || settings.reverse_input_filename) {
272 report_conditional_error_and_exit(!!settings.aec_dump_input_filename,
aluebs-webrtc 2016/04/26 04:33:39 double negation?
peah-webrtc 2016/04/26 07:19:29 aec_dump_input_filename is an optional, and I want
aluebs-webrtc 2016/04/27 16:06:47 Oh, I thought it would cast automatically to bool.
peah-webrtc 2016/05/09 11:37:30 Acknowledged.
273 "Error: The aec dump cannot be specified "
274 "together with input wav files!\n");
275
276 report_conditional_error_and_exit(!settings.input_filename,
277 "Error: When operating at wav files, the "
278 "input wav filename must be "
279 "specified!\n");
280
281 report_conditional_error_and_exit(
282 settings.reverse_output_filename && !settings.reverse_input_filename,
283 "Error: When operating at wav files, the reverse input wav filename "
284 "must be specified if the reverse output wav filename is specified!\n");
285 } else {
286 report_conditional_error_and_exit(!settings.aec_dump_input_filename,
287 "Error: Either the aec dump or the wav "
288 "input files must be specified!\n");
289 }
290
291 report_conditional_error_and_exit(
292 settings.use_aec && *settings.use_aec && settings.use_aecm &&
293 *settings.use_aecm,
294 "Error: The AEC and the AECM cannot be activated at the same time!\n");
295
296 report_conditional_error_and_exit(
297 settings.output_sample_rate_hz &&
298 (*settings.output_sample_rate_hz <= 0 ||
299 *settings.output_sample_rate_hz > 48000),
aluebs-webrtc 2016/04/26 04:33:39 Why do we impose this limit? The APM can handle an
peah-webrtc 2016/04/28 07:41:11 Done.
300 "Error: --output_sample_rate_hz must be betweem 0 and 48000!\n");
301
302 report_conditional_error_and_exit(
aluebs-webrtc 2016/04/26 04:33:39 All these checks for a single parameter can be imp
peah-webrtc 2016/04/26 07:19:29 No, that does not work if you want to have tri-sta
aluebs-webrtc 2016/04/27 16:06:47 Good point.
peah-webrtc 2016/05/09 11:37:30 Acknowledged.
303 settings.reverse_output_sample_rate_hz &&
304 (*settings.reverse_output_sample_rate_hz <= 0 ||
305 *settings.reverse_output_sample_rate_hz > 48000),
306 "Error: --reverse_output_sample_rate_hz must be betweem 0 and 48000!\n");
307
308 report_conditional_error_and_exit(
309 settings.output_num_channels && (*settings.output_num_channels <= 0 ||
310 *settings.output_num_channels > 2),
aluebs-webrtc 2016/04/26 04:33:39 Why do we impose this limit? The APM can handle an
peah-webrtc 2016/04/26 07:19:29 Done.
311 "Error: --output_num_channels must be 1 or 2!\n");
312
313 report_conditional_error_and_exit(
314 settings.reverse_output_num_channels &&
315 (*settings.reverse_output_num_channels <= 0 ||
316 *settings.reverse_output_num_channels > 2),
317 "Error: --reverse_output_num_channels must be 1 or 2!\n");
318
319 report_conditional_error_and_exit(
320 settings.use_bf && *settings.use_bf && !settings.microphone_positions,
321 "Error: --mic_positions must be specified when the beamformer is "
322 "activated.\n");
323
324 report_conditional_error_and_exit(
325 settings.target_angle_degrees < 0 || settings.target_angle_degrees > 90,
aluebs-webrtc 2016/04/26 04:33:39 The angle can definitively go between 0 and 359 de
peah-webrtc 2016/04/26 07:19:29 My mistake. I think it is anyway nice to impose a
aluebs-webrtc 2016/04/27 16:06:47 I don't mind imposing this limit.
peah-webrtc 2016/05/09 11:37:30 Acknowledged.
326 "Error: -target_angle_degrees must be specified between 0 and 90.\n");
327
328 report_conditional_error_and_exit(
329 settings.aec_suppression_level &&
330 ((*settings.aec_suppression_level) < 0 ||
331 (*settings.aec_suppression_level) > 2),
332 "Error: --aec_suppression_level must be specified between 0 and 2.\n");
333
334 report_conditional_error_and_exit(
335 settings.aecm_routing_mode && ((*settings.aecm_routing_mode) < 0 ||
336 (*settings.aecm_routing_mode) > 4),
337 "Error: --aecm_routing_mode must be specified between 0 and 4.\n");
338
339 report_conditional_error_and_exit(
340 settings.agc_target_level && ((*settings.agc_target_level) < 0 ||
341 (*settings.agc_target_level) > 31),
342 "Error: --agc_target_level must be specified between 0 and 31.\n");
343
344 report_conditional_error_and_exit(
345 settings.agc_compression_gain && ((*settings.agc_compression_gain) < 0 ||
346 (*settings.agc_compression_gain) > 90),
347 "Error: --agc_compression_gain must be specified between 0 and 90.\n");
348
349 report_conditional_error_and_exit(
350 settings.vad_likelihood &&
351 ((*settings.vad_likelihood) < 0 || (*settings.vad_likelihood) > 3),
352 "Error: --vad_likelihood must be specified between 0 and 3.\n");
353
354 report_conditional_error_and_exit(
355 settings.ns_level &&
356 ((*settings.ns_level) < 0 || (*settings.ns_level) > 3),
357 "Error: --ns_level must be specified between 0 and 3.\n");
358
359 auto valid_wav_name = [](const std::string& wav_file_name) {
aluebs-webrtc 2016/04/26 04:33:39 Why isn't this a normal function?
peah-webrtc 2016/04/26 07:19:29 The lambda/function is only used in the lines belo
aluebs-webrtc 2016/04/27 16:06:46 Personally I find interleaved lambdas to be less r
peah-webrtc 2016/04/28 07:41:11 Acknowledged.
360 if (wav_file_name.size() < 5) {
361 return false;
362 }
363 if ((wav_file_name.compare(wav_file_name.size() - 4, 4, ".wav") == 0) ||
364 (wav_file_name.compare(wav_file_name.size() - 4, 4, ".WAV") == 0)) {
365 return true;
366 }
367 return false;
368 };
369
370 report_conditional_error_and_exit(
371 settings.input_filename && (!valid_wav_name(*settings.input_filename)),
372 "Error: --i must be a valid .wav file name.\n");
373
374 report_conditional_error_and_exit(
375 settings.output_filename && (!valid_wav_name(*settings.output_filename)),
376 "Error: --o must be a valid .wav file name.\n");
377
378 report_conditional_error_and_exit(
379 settings.reverse_input_filename &&
380 (!valid_wav_name(*settings.reverse_input_filename)),
381 "Error: --ri must be a valid .wav file name.\n");
382
383 report_conditional_error_and_exit(
384 settings.reverse_output_filename &&
385 (!valid_wav_name(*settings.reverse_output_filename)),
386 "Error: --ro must be a valid .wav file name.\n");
35 } 387 }
36 388
37 } // namespace 389 } // namespace
38 390
39 DEFINE_string(dump, "", "Name of the aecdump debug file to read from.");
40 DEFINE_string(i, "", "Name of the capture input stream file to read from.");
41 DEFINE_string(
42 o,
43 "out.wav",
44 "Name of the output file to write the processed capture stream to.");
45 DEFINE_string(ri, "", "Name of the render input stream file to read from.");
46 DEFINE_string(
47 ro,
48 "out_reverse.wav",
49 "Name of the output file to write the processed render stream to.");
50 DEFINE_int32(out_channels, 1, "Number of output channels.");
51 const bool out_channels_dummy =
52 google::RegisterFlagValidator(&FLAGS_out_channels, &ValidateOutChannels);
53 DEFINE_int32(rev_out_channels, 1, "Number of reverse output channels.");
54 const bool rev_out_channels_dummy =
55 google::RegisterFlagValidator(&FLAGS_rev_out_channels,
56 &ValidateOutChannels);
57 DEFINE_int32(out_sample_rate, 48000, "Output sample rate in Hz.");
58 DEFINE_int32(rev_out_sample_rate, 48000, "Reverse output sample rate in Hz.");
59 DEFINE_string(mic_positions, "",
60 "Space delimited cartesian coordinates of microphones in meters. "
61 "The coordinates of each point are contiguous. "
62 "For a two element array: \"x1 y1 z1 x2 y2 z2\"");
63 DEFINE_double(
64 target_angle_degrees,
65 90,
66 "The azimuth of the target in degrees. Only applies to beamforming.");
67
68 DEFINE_bool(aec, false, "Enable echo cancellation.");
69 DEFINE_bool(agc, false, "Enable automatic gain control.");
70 DEFINE_bool(hpf, false, "Enable high-pass filtering.");
71 DEFINE_bool(ns, false, "Enable noise suppression.");
72 DEFINE_bool(ts, false, "Enable transient suppression.");
73 DEFINE_bool(bf, false, "Enable beamforming.");
74 DEFINE_bool(ie, false, "Enable intelligibility enhancer.");
75 DEFINE_bool(all, false, "Enable all components.");
76
77 DEFINE_int32(ns_level, -1, "Noise suppression level [0 - 3].");
78
79 DEFINE_bool(perf, false, "Enable performance tests.");
80
81 namespace webrtc {
82 namespace {
83
84 const int kChunksPerSecond = 100;
85 const char kUsage[] =
86 "Command-line tool to run audio processing on WAV files. Accepts either\n"
87 "an input capture WAV file or protobuf debug dump and writes to an output\n"
88 "WAV file.\n"
89 "\n"
90 "All components are disabled by default.";
91
92 } // namespace
93
94 int main(int argc, char* argv[]) { 391 int main(int argc, char* argv[]) {
95 google::SetUsageMessage(kUsage); 392 google::SetUsageMessage(kUsageDescription);
96 google::ParseCommandLineFlags(&argc, &argv, true); 393 google::ParseCommandLineFlags(&argc, &argv, true);
97 394
98 if (!((FLAGS_i.empty()) ^ (FLAGS_dump.empty()))) { 395 SimulationSettings settings = CreateSettings();
99 fprintf(stderr, 396 PerformBasicParameterSanityChecks(settings);
100 "An input file must be specified with either -i or -dump.\n"); 397 std::unique_ptr<AudioProcessingSimulator> processor;
101 return 1; 398
102 } 399 if (settings.aec_dump_input_filename) {
103 400 processor.reset(new AecDumpBasedSimulator(settings));
104 test::TraceToStderr trace_to_stderr(true);
105 Config config;
106 if (FLAGS_bf || FLAGS_all) {
107 if (FLAGS_mic_positions.empty()) {
108 fprintf(stderr, "-mic_positions must be specified when -bf is used.\n");
109 return 1;
110 }
111 config.Set<Beamforming>(new Beamforming(
112 true, ParseArrayGeometry(FLAGS_mic_positions),
113 SphericalPointf(DegreesToRadians(FLAGS_target_angle_degrees), 0.f,
114 1.f)));
115 }
116 config.Set<ExperimentalNs>(new ExperimentalNs(FLAGS_ts || FLAGS_all));
117 config.Set<Intelligibility>(new Intelligibility(FLAGS_ie || FLAGS_all));
118
119 std::unique_ptr<AudioProcessing> ap(AudioProcessing::Create(config));
120 RTC_CHECK_EQ(kNoErr, ap->echo_cancellation()->Enable(FLAGS_aec || FLAGS_all));
121 RTC_CHECK_EQ(kNoErr, ap->gain_control()->Enable(FLAGS_agc || FLAGS_all));
122 RTC_CHECK_EQ(kNoErr, ap->high_pass_filter()->Enable(FLAGS_hpf || FLAGS_all));
123 RTC_CHECK_EQ(kNoErr, ap->noise_suppression()->Enable(FLAGS_ns || FLAGS_all));
124 if (FLAGS_ns_level != -1) {
125 RTC_CHECK_EQ(kNoErr,
126 ap->noise_suppression()->set_level(
127 static_cast<NoiseSuppression::Level>(FLAGS_ns_level)));
128 }
129 ap->set_stream_key_pressed(FLAGS_ts);
130
131 std::unique_ptr<AudioFileProcessor> processor;
132 auto out_file = std::unique_ptr<WavWriter>(new WavWriter(
133 FLAGS_o, FLAGS_out_sample_rate, static_cast<size_t>(FLAGS_out_channels)));
134 std::cout << FLAGS_o << ": " << out_file->FormatAsString() << std::endl;
135 if (FLAGS_dump.empty()) {
136 auto in_file = std::unique_ptr<WavReader>(new WavReader(FLAGS_i));
137 std::cout << FLAGS_i << ": " << in_file->FormatAsString() << std::endl;
138 std::unique_ptr<WavReader> reverse_in_file;
139 std::unique_ptr<WavWriter> reverse_out_file;
140 if (!FLAGS_ri.empty()) {
141 reverse_in_file.reset(new WavReader(FLAGS_ri));
142 reverse_out_file.reset(new WavWriter(
143 FLAGS_ro,
144 FLAGS_rev_out_sample_rate,
145 static_cast<size_t>(FLAGS_rev_out_channels)));
146 std::cout << FLAGS_ri << ": "
147 << reverse_in_file->FormatAsString() << std::endl;
148 std::cout << FLAGS_ro << ": "
149 << reverse_out_file->FormatAsString() << std::endl;
150 }
151 processor.reset(new WavFileProcessor(std::move(ap),
152 std::move(in_file),
153 std::move(out_file),
154 std::move(reverse_in_file),
155 std::move(reverse_out_file)));
156
157 } else { 401 } else {
158 processor.reset(new AecDumpFileProcessor( 402 processor.reset(new WavBasedSimulator(settings));
159 std::move(ap), fopen(FLAGS_dump.c_str(), "rb"), std::move(out_file))); 403 }
160 } 404
161 405 processor->Process();
162 int num_chunks = 0; 406
163 while (processor->ProcessChunk()) { 407 int num_fwd_chunks_processed = processor->get_num_process_stream_calls();
aluebs-webrtc 2016/04/26 04:33:39 I don't think this temp variable is necessary, but
peah-webrtc 2016/04/26 07:19:29 Done.
164 trace_to_stderr.SetTimeSeconds(num_chunks * 1.f / kChunksPerSecond); 408
165 ++num_chunks; 409 if (settings.report_performance) {
166 }
167
168 if (FLAGS_perf) {
169 const auto& proc_time = processor->proc_time(); 410 const auto& proc_time = processor->proc_time();
170 int64_t exec_time_us = proc_time.sum.Microseconds(); 411 int64_t exec_time_us = proc_time.sum.Microseconds();
171 printf( 412 printf(
172 "\nExecution time: %.3f s, File time: %.2f s\n" 413 "\nExecution time: %.3f s, File time: %.2f s\n"
173 "Time per chunk (mean, max, min):\n%.0f us, %.0f us, %.0f us\n", 414 "Time per fwd stream chunk (mean, max, min):\n%.0f us, %.0f us, %.0f "
174 exec_time_us * 1e-6, num_chunks * 1.f / kChunksPerSecond, 415 "us\n",
175 exec_time_us * 1.f / num_chunks, 1.f * proc_time.max.Microseconds(), 416 exec_time_us * 1e-6, num_fwd_chunks_processed * 1.f /
176 1.f * proc_time.min.Microseconds()); 417 AudioProcessingSimulator::kChunksPerSecond,
418 exec_time_us * 1.f / num_fwd_chunks_processed,
419 1.f * proc_time.max.Microseconds(), 1.f * proc_time.min.Microseconds());
420 }
421
422 if (settings.report_bitexactness && settings.aec_dump_input_filename) {
aluebs-webrtc 2016/04/26 04:33:39 It should probably be checked in your sanity funct
peah-webrtc 2016/04/26 07:19:29 Good point! Done.
423 if (processor->OutputWasBitexact()) {
424 printf("The processing was bitexact.\n");
425 } else {
426 printf("The processing was not bitexact.\n");
427 }
177 } 428 }
178 429
179 return 0; 430 return 0;
180 } 431 }
181 432
433 } // namespace test
182 } // namespace webrtc 434 } // namespace webrtc
183 435
184 int main(int argc, char* argv[]) { 436 int main(int argc, char* argv[]) {
185 return webrtc::main(argc, argv); 437 return webrtc::test::main(argc, argv);
186 } 438 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698