blob: 185bc142d508a316a71a6155dfdf63f0371248cc [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
leozwang@webrtc.org9a85d8e2012-03-16 18:03:18 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
andrew@webrtc.org81865342012-10-27 00:28:27 +000011#include <math.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000012#include <stdio.h>
13#include <string.h>
14#ifdef WEBRTC_ANDROID
15#include <sys/stat.h>
16#endif
17
andrew@webrtc.org81865342012-10-27 00:28:27 +000018#include <algorithm>
kwiberg62eaacf2016-02-17 06:39:05 -080019#include <memory>
andrew@webrtc.org81865342012-10-27 00:28:27 +000020
Peter Kasting69558702016-01-12 16:26:35 -080021#include "webrtc/base/format_macros.h"
andrew@webrtc.org22858d42013-10-23 14:07:17 +000022#include "webrtc/common.h"
kma@webrtc.org0e739502012-12-07 15:26:28 +000023#include "webrtc/modules/audio_processing/include/audio_processing.h"
Andrew MacDonaldcb05b722015-05-07 22:17:51 -070024#include "webrtc/modules/audio_processing/test/protobuf_utils.h"
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000025#include "webrtc/modules/audio_processing/test/test_utils.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010026#include "webrtc/modules/include/module_common_types.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010027#include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
28#include "webrtc/system_wrappers/include/tick_util.h"
kjellander@webrtc.org10abe252012-12-17 18:28:07 +000029#include "webrtc/test/testsupport/fileutils.h"
kma@webrtc.org0e739502012-12-07 15:26:28 +000030#include "webrtc/test/testsupport/perf_test.h"
leozwang@webrtc.orga3736342012-03-16 21:36:00 +000031#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
pbos@webrtc.org8c34cee2013-05-28 09:24:03 +000032#include "gtest/gtest.h"
leozwang@webrtc.org534e4952012-10-22 21:21:52 +000033#include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h"
leozwang@webrtc.orga3736342012-03-16 21:36:00 +000034#else
pbos@webrtc.org8c34cee2013-05-28 09:24:03 +000035#include "testing/gtest/include/gtest/gtest.h"
kjellander78ddd732016-02-09 08:13:06 -080036#include "webrtc/modules/audio_processing/debug.pb.h"
leozwang@webrtc.orga3736342012-03-16 21:36:00 +000037#endif
niklase@google.com470e71d2011-07-07 08:21:25 +000038
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000039namespace webrtc {
andrew@webrtc.org3119ecf2011-11-01 17:00:18 +000040
ajm@google.com808e0e02011-08-03 21:08:51 +000041using webrtc::audioproc::Event;
42using webrtc::audioproc::Init;
43using webrtc::audioproc::ReverseStream;
44using webrtc::audioproc::Stream;
45
46namespace {
niklase@google.com470e71d2011-07-07 08:21:25 +000047
andrew@webrtc.org94c74132011-09-19 15:17:57 +000048void PrintStat(const AudioProcessing::Statistic& stat) {
49 printf("%d, %d, %d\n", stat.average,
50 stat.maximum,
51 stat.minimum);
52}
53
niklase@google.com470e71d2011-07-07 08:21:25 +000054void usage() {
55 printf(
ajm@google.com808e0e02011-08-03 21:08:51 +000056 "Usage: process_test [options] [-pb PROTOBUF_FILE]\n"
57 " [-ir REVERSE_FILE] [-i PRIMARY_FILE] [-o OUT_FILE]\n");
niklase@google.com470e71d2011-07-07 08:21:25 +000058 printf(
59 "process_test is a test application for AudioProcessing.\n\n"
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000060 "When a protobuf debug file is available, specify it with -pb. Alternately,\n"
61 "when -ir or -i is used, the specified files will be processed directly in\n"
62 "a simulation mode. Otherwise the full set of legacy test files is expected\n"
63 "to be present in the working directory. OUT_FILE should be specified\n"
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +000064 "without extension to support both raw and wav output.\n\n");
niklase@google.com470e71d2011-07-07 08:21:25 +000065 printf("Options\n");
ajm@google.com808e0e02011-08-03 21:08:51 +000066 printf("General configuration (only used for the simulation mode):\n");
niklase@google.com470e71d2011-07-07 08:21:25 +000067 printf(" -fs SAMPLE_RATE_HZ\n");
68 printf(" -ch CHANNELS_IN CHANNELS_OUT\n");
69 printf(" -rch REVERSE_CHANNELS\n");
70 printf("\n");
71 printf("Component configuration:\n");
72 printf(
73 "All components are disabled by default. Each block below begins with a\n"
74 "flag to enable the component with default settings. The subsequent flags\n"
75 "in the block are used to provide configuration settings.\n");
76 printf("\n -aec Echo cancellation\n");
77 printf(" --drift_compensation\n");
78 printf(" --no_drift_compensation\n");
andrew@webrtc.org94c74132011-09-19 15:17:57 +000079 printf(" --no_echo_metrics\n");
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +000080 printf(" --no_delay_logging\n");
andrew@webrtc.orgdff69c52013-04-30 23:01:09 +000081 printf(" --aec_suppression_level LEVEL [0 - 2]\n");
andrew@webrtc.org22858d42013-10-23 14:07:17 +000082 printf(" --extended_filter\n");
bjornv@webrtc.org84f8ec12014-06-19 12:14:33 +000083 printf(" --no_reported_delay\n");
peah6ebc4d32016-03-07 16:59:39 -080084 printf(" --aec3\n");
peah0332c2d2016-04-15 11:23:33 -070085 printf(" --refined_adaptive_filter\n");
niklase@google.com470e71d2011-07-07 08:21:25 +000086 printf("\n -aecm Echo control mobile\n");
bjornv@google.com238a0222011-07-15 14:51:52 +000087 printf(" --aecm_echo_path_in_file FILE\n");
88 printf(" --aecm_echo_path_out_file FILE\n");
andrew@webrtc.org1acb3b32013-04-26 00:39:27 +000089 printf(" --no_comfort_noise\n");
90 printf(" --routing_mode MODE [0 - 4]\n");
niklase@google.com470e71d2011-07-07 08:21:25 +000091 printf("\n -agc Gain control\n");
92 printf(" --analog\n");
93 printf(" --adaptive_digital\n");
94 printf(" --fixed_digital\n");
95 printf(" --target_level LEVEL\n");
96 printf(" --compression_gain GAIN\n");
97 printf(" --limiter\n");
98 printf(" --no_limiter\n");
99 printf("\n -hpf High pass filter\n");
100 printf("\n -ns Noise suppression\n");
101 printf(" --ns_low\n");
102 printf(" --ns_moderate\n");
103 printf(" --ns_high\n");
104 printf(" --ns_very_high\n");
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000105 printf(" --ns_prob_file FILE\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000106 printf("\n -vad Voice activity detection\n");
ajm@google.com808e0e02011-08-03 21:08:51 +0000107 printf(" --vad_out_file FILE\n");
andrew@webrtc.orgb13a7d52014-03-27 00:11:11 +0000108 printf("\n -expns Experimental noise suppression\n");
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000109 printf("\n Level metrics (enabled by default)\n");
110 printf(" --no_level_metrics\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000111 printf("\n");
112 printf("Modifiers:\n");
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000113 printf(" --noasm Disable SSE optimization.\n");
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000114 printf(" --add_delay DELAY Add DELAY ms to input value.\n");
115 printf(" --delay DELAY Override input delay with DELAY ms.\n");
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000116 printf(" --perf Measure performance.\n");
117 printf(" --quiet Suppress text output.\n");
118 printf(" --no_progress Suppress progress.\n");
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000119 printf(" --raw_output Raw output instead of WAV file.\n");
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000120 printf(" --debug_file FILE Dump a debug recording.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000121}
122
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000123static float MicLevel2Gain(int level) {
124 return pow(10.0f, ((level - 127.0f) / 128.0f * 40.0f) / 20.0f);
andrew@webrtc.org81865342012-10-27 00:28:27 +0000125}
126
127static void SimulateMic(int mic_level, AudioFrame* frame) {
128 mic_level = std::min(std::max(mic_level, 0), 255);
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000129 float mic_gain = MicLevel2Gain(mic_level);
andrew@webrtc.org81865342012-10-27 00:28:27 +0000130 int num_samples = frame->samples_per_channel_ * frame->num_channels_;
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000131 float v;
andrew@webrtc.org81865342012-10-27 00:28:27 +0000132 for (int n = 0; n < num_samples; n++) {
133 v = floor(frame->data_[n] * mic_gain + 0.5);
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000134 v = std::max(std::min(32767.0f, v), -32768.0f);
andrew@webrtc.org81865342012-10-27 00:28:27 +0000135 frame->data_[n] = static_cast<int16_t>(v);
136 }
137}
138
niklase@google.com470e71d2011-07-07 08:21:25 +0000139// void function for gtest.
140void void_main(int argc, char* argv[]) {
141 if (argc > 1 && strcmp(argv[1], "--help") == 0) {
142 usage();
143 return;
144 }
145
146 if (argc < 2) {
147 printf("Did you mean to run without arguments?\n");
148 printf("Try `process_test --help' for more information.\n\n");
149 }
150
kwiberg62eaacf2016-02-17 06:39:05 -0800151 std::unique_ptr<AudioProcessing> apm(AudioProcessing::Create());
andrew@webrtc.orgf3930e92013-09-18 22:37:32 +0000152 ASSERT_TRUE(apm.get() != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000153
ajm@google.com808e0e02011-08-03 21:08:51 +0000154 const char* pb_filename = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000155 const char* far_filename = NULL;
156 const char* near_filename = NULL;
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000157 std::string out_filename;
niklase@google.com470e71d2011-07-07 08:21:25 +0000158 const char* vad_out_filename = NULL;
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000159 const char* ns_prob_filename = NULL;
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000160 const char* aecm_echo_path_in_filename = NULL;
161 const char* aecm_echo_path_out_filename = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000162
163 int32_t sample_rate_hz = 16000;
niklase@google.com470e71d2011-07-07 08:21:25 +0000164
Peter Kasting69558702016-01-12 16:26:35 -0800165 size_t num_capture_input_channels = 1;
166 size_t num_capture_output_channels = 1;
167 size_t num_render_channels = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000168
169 int samples_per_channel = sample_rate_hz / 100;
170
171 bool simulating = false;
172 bool perf_testing = false;
173 bool verbose = true;
174 bool progress = true;
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000175 bool raw_output = false;
andrew@webrtc.org4b13fc92011-11-09 19:27:11 +0000176 int extra_delay_ms = 0;
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000177 int override_delay_ms = 0;
Bjorn Volckerbeb97982015-04-28 13:52:50 +0200178 Config config;
niklase@google.com470e71d2011-07-07 08:21:25 +0000179
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000180 ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(true));
niklase@google.com470e71d2011-07-07 08:21:25 +0000181 for (int i = 1; i < argc; i++) {
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000182 if (strcmp(argv[i], "-pb") == 0) {
ajm@google.com808e0e02011-08-03 21:08:51 +0000183 i++;
184 ASSERT_LT(i, argc) << "Specify protobuf filename after -pb";
185 pb_filename = argv[i];
186
187 } else if (strcmp(argv[i], "-ir") == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000188 i++;
189 ASSERT_LT(i, argc) << "Specify filename after -ir";
190 far_filename = argv[i];
191 simulating = true;
192
193 } else if (strcmp(argv[i], "-i") == 0) {
194 i++;
195 ASSERT_LT(i, argc) << "Specify filename after -i";
196 near_filename = argv[i];
197 simulating = true;
198
199 } else if (strcmp(argv[i], "-o") == 0) {
200 i++;
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000201 ASSERT_LT(i, argc) << "Specify filename without extension after -o";
niklase@google.com470e71d2011-07-07 08:21:25 +0000202 out_filename = argv[i];
203
204 } else if (strcmp(argv[i], "-fs") == 0) {
205 i++;
206 ASSERT_LT(i, argc) << "Specify sample rate after -fs";
207 ASSERT_EQ(1, sscanf(argv[i], "%d", &sample_rate_hz));
208 samples_per_channel = sample_rate_hz / 100;
209
niklase@google.com470e71d2011-07-07 08:21:25 +0000210 } else if (strcmp(argv[i], "-ch") == 0) {
211 i++;
212 ASSERT_LT(i + 1, argc) << "Specify number of channels after -ch";
Peter Kasting69558702016-01-12 16:26:35 -0800213 ASSERT_EQ(1, sscanf(argv[i], "%" PRIuS, &num_capture_input_channels));
niklase@google.com470e71d2011-07-07 08:21:25 +0000214 i++;
Peter Kasting69558702016-01-12 16:26:35 -0800215 ASSERT_EQ(1, sscanf(argv[i], "%" PRIuS, &num_capture_output_channels));
niklase@google.com470e71d2011-07-07 08:21:25 +0000216
niklase@google.com470e71d2011-07-07 08:21:25 +0000217 } else if (strcmp(argv[i], "-rch") == 0) {
218 i++;
219 ASSERT_LT(i, argc) << "Specify number of channels after -rch";
Peter Kasting69558702016-01-12 16:26:35 -0800220 ASSERT_EQ(1, sscanf(argv[i], "%" PRIuS, &num_render_channels));
niklase@google.com470e71d2011-07-07 08:21:25 +0000221
niklase@google.com470e71d2011-07-07 08:21:25 +0000222 } else if (strcmp(argv[i], "-aec") == 0) {
223 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +0000224 ASSERT_EQ(apm->kNoError,
225 apm->echo_cancellation()->enable_metrics(true));
226 ASSERT_EQ(apm->kNoError,
227 apm->echo_cancellation()->enable_delay_logging(true));
niklase@google.com470e71d2011-07-07 08:21:25 +0000228
niklase@google.com470e71d2011-07-07 08:21:25 +0000229 } else if (strcmp(argv[i], "--drift_compensation") == 0) {
230 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
231 // TODO(ajm): this is enabled in the VQE test app by default. Investigate
232 // why it can give better performance despite passing zeros.
233 ASSERT_EQ(apm->kNoError,
234 apm->echo_cancellation()->enable_drift_compensation(true));
235 } else if (strcmp(argv[i], "--no_drift_compensation") == 0) {
236 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
237 ASSERT_EQ(apm->kNoError,
238 apm->echo_cancellation()->enable_drift_compensation(false));
239
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000240 } else if (strcmp(argv[i], "--no_echo_metrics") == 0) {
241 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
242 ASSERT_EQ(apm->kNoError,
243 apm->echo_cancellation()->enable_metrics(false));
244
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +0000245 } else if (strcmp(argv[i], "--no_delay_logging") == 0) {
246 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
247 ASSERT_EQ(apm->kNoError,
248 apm->echo_cancellation()->enable_delay_logging(false));
249
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000250 } else if (strcmp(argv[i], "--no_level_metrics") == 0) {
251 ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(false));
252
andrew@webrtc.orgdff69c52013-04-30 23:01:09 +0000253 } else if (strcmp(argv[i], "--aec_suppression_level") == 0) {
254 i++;
255 ASSERT_LT(i, argc) << "Specify level after --aec_suppression_level";
256 int suppression_level;
257 ASSERT_EQ(1, sscanf(argv[i], "%d", &suppression_level));
258 ASSERT_EQ(apm->kNoError,
259 apm->echo_cancellation()->set_suppression_level(
260 static_cast<webrtc::EchoCancellation::SuppressionLevel>(
261 suppression_level)));
262
andrew@webrtc.org22858d42013-10-23 14:07:17 +0000263 } else if (strcmp(argv[i], "--extended_filter") == 0) {
Henrik Lundin441f6342015-06-09 16:03:13 +0200264 config.Set<ExtendedFilter>(new ExtendedFilter(true));
andrew@webrtc.org22858d42013-10-23 14:07:17 +0000265
bjornv@webrtc.org84f8ec12014-06-19 12:14:33 +0000266 } else if (strcmp(argv[i], "--no_reported_delay") == 0) {
henrik.lundin0f133b92015-07-02 00:17:55 -0700267 config.Set<DelayAgnostic>(new DelayAgnostic(true));
268
269 } else if (strcmp(argv[i], "--delay_agnostic") == 0) {
270 config.Set<DelayAgnostic>(new DelayAgnostic(true));
bjornv@webrtc.org84f8ec12014-06-19 12:14:33 +0000271
peah6ebc4d32016-03-07 16:59:39 -0800272 } else if (strcmp(argv[i], "--aec3") == 0) {
273 config.Set<EchoCanceller3>(new EchoCanceller3(true));
peaha332e2d2016-02-17 01:11:16 -0800274
peah0332c2d2016-04-15 11:23:33 -0700275 } else if (strcmp(argv[i], "--refined_adaptive_filter") == 0) {
276 config.Set<RefinedAdaptiveFilter>(new RefinedAdaptiveFilter(true));
277
niklase@google.com470e71d2011-07-07 08:21:25 +0000278 } else if (strcmp(argv[i], "-aecm") == 0) {
279 ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(true));
280
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000281 } else if (strcmp(argv[i], "--aecm_echo_path_in_file") == 0) {
282 i++;
283 ASSERT_LT(i, argc) << "Specify filename after --aecm_echo_path_in_file";
284 aecm_echo_path_in_filename = argv[i];
285
286 } else if (strcmp(argv[i], "--aecm_echo_path_out_file") == 0) {
287 i++;
288 ASSERT_LT(i, argc) << "Specify filename after --aecm_echo_path_out_file";
289 aecm_echo_path_out_filename = argv[i];
290
andrew@webrtc.org1acb3b32013-04-26 00:39:27 +0000291 } else if (strcmp(argv[i], "--no_comfort_noise") == 0) {
292 ASSERT_EQ(apm->kNoError,
293 apm->echo_control_mobile()->enable_comfort_noise(false));
294
295 } else if (strcmp(argv[i], "--routing_mode") == 0) {
296 i++;
297 ASSERT_LT(i, argc) << "Specify mode after --routing_mode";
298 int routing_mode;
299 ASSERT_EQ(1, sscanf(argv[i], "%d", &routing_mode));
300 ASSERT_EQ(apm->kNoError,
301 apm->echo_control_mobile()->set_routing_mode(
302 static_cast<webrtc::EchoControlMobile::RoutingMode>(
303 routing_mode)));
304
niklase@google.com470e71d2011-07-07 08:21:25 +0000305 } else if (strcmp(argv[i], "-agc") == 0) {
306 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
307
308 } else if (strcmp(argv[i], "--analog") == 0) {
309 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
310 ASSERT_EQ(apm->kNoError,
311 apm->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
312
313 } else if (strcmp(argv[i], "--adaptive_digital") == 0) {
314 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
315 ASSERT_EQ(apm->kNoError,
316 apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
317
318 } else if (strcmp(argv[i], "--fixed_digital") == 0) {
319 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
320 ASSERT_EQ(apm->kNoError,
321 apm->gain_control()->set_mode(GainControl::kFixedDigital));
322
323 } else if (strcmp(argv[i], "--target_level") == 0) {
324 i++;
325 int level;
326 ASSERT_EQ(1, sscanf(argv[i], "%d", &level));
327
328 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
329 ASSERT_EQ(apm->kNoError,
330 apm->gain_control()->set_target_level_dbfs(level));
331
332 } else if (strcmp(argv[i], "--compression_gain") == 0) {
333 i++;
334 int gain;
335 ASSERT_EQ(1, sscanf(argv[i], "%d", &gain));
336
337 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
338 ASSERT_EQ(apm->kNoError,
339 apm->gain_control()->set_compression_gain_db(gain));
340
341 } else if (strcmp(argv[i], "--limiter") == 0) {
342 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
343 ASSERT_EQ(apm->kNoError,
344 apm->gain_control()->enable_limiter(true));
345
346 } else if (strcmp(argv[i], "--no_limiter") == 0) {
347 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
348 ASSERT_EQ(apm->kNoError,
349 apm->gain_control()->enable_limiter(false));
350
351 } else if (strcmp(argv[i], "-hpf") == 0) {
352 ASSERT_EQ(apm->kNoError, apm->high_pass_filter()->Enable(true));
353
354 } else if (strcmp(argv[i], "-ns") == 0) {
355 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
356
357 } else if (strcmp(argv[i], "--ns_low") == 0) {
358 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
359 ASSERT_EQ(apm->kNoError,
360 apm->noise_suppression()->set_level(NoiseSuppression::kLow));
361
362 } else if (strcmp(argv[i], "--ns_moderate") == 0) {
363 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
364 ASSERT_EQ(apm->kNoError,
365 apm->noise_suppression()->set_level(NoiseSuppression::kModerate));
366
367 } else if (strcmp(argv[i], "--ns_high") == 0) {
368 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
369 ASSERT_EQ(apm->kNoError,
370 apm->noise_suppression()->set_level(NoiseSuppression::kHigh));
371
372 } else if (strcmp(argv[i], "--ns_very_high") == 0) {
373 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
374 ASSERT_EQ(apm->kNoError,
375 apm->noise_suppression()->set_level(NoiseSuppression::kVeryHigh));
376
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000377 } else if (strcmp(argv[i], "--ns_prob_file") == 0) {
378 i++;
379 ASSERT_LT(i, argc) << "Specify filename after --ns_prob_file";
380 ns_prob_filename = argv[i];
381
niklase@google.com470e71d2011-07-07 08:21:25 +0000382 } else if (strcmp(argv[i], "-vad") == 0) {
383 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
384
andrew@webrtc.org89752612012-10-12 16:41:45 +0000385 } else if (strcmp(argv[i], "--vad_very_low") == 0) {
386 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
387 ASSERT_EQ(apm->kNoError,
388 apm->voice_detection()->set_likelihood(
389 VoiceDetection::kVeryLowLikelihood));
390
391 } else if (strcmp(argv[i], "--vad_low") == 0) {
392 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
393 ASSERT_EQ(apm->kNoError,
394 apm->voice_detection()->set_likelihood(
395 VoiceDetection::kLowLikelihood));
396
397 } else if (strcmp(argv[i], "--vad_moderate") == 0) {
398 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
399 ASSERT_EQ(apm->kNoError,
400 apm->voice_detection()->set_likelihood(
401 VoiceDetection::kModerateLikelihood));
402
403 } else if (strcmp(argv[i], "--vad_high") == 0) {
404 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
405 ASSERT_EQ(apm->kNoError,
406 apm->voice_detection()->set_likelihood(
407 VoiceDetection::kHighLikelihood));
408
niklase@google.com470e71d2011-07-07 08:21:25 +0000409 } else if (strcmp(argv[i], "--vad_out_file") == 0) {
410 i++;
411 ASSERT_LT(i, argc) << "Specify filename after --vad_out_file";
412 vad_out_filename = argv[i];
413
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +0000414 } else if (strcmp(argv[i], "-expns") == 0) {
aluebs@webrtc.org9825afc2014-06-30 17:39:53 +0000415 config.Set<ExperimentalNs>(new ExperimentalNs(true));
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +0000416
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000417 } else if (strcmp(argv[i], "--noasm") == 0) {
418 WebRtc_GetCPUInfo = WebRtc_GetCPUInfoNoASM;
419 // We need to reinitialize here if components have already been enabled.
420 ASSERT_EQ(apm->kNoError, apm->Initialize());
421
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000422 } else if (strcmp(argv[i], "--add_delay") == 0) {
andrew@webrtc.org4b13fc92011-11-09 19:27:11 +0000423 i++;
424 ASSERT_EQ(1, sscanf(argv[i], "%d", &extra_delay_ms));
425
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000426 } else if (strcmp(argv[i], "--delay") == 0) {
427 i++;
428 ASSERT_EQ(1, sscanf(argv[i], "%d", &override_delay_ms));
429
niklase@google.com470e71d2011-07-07 08:21:25 +0000430 } else if (strcmp(argv[i], "--perf") == 0) {
431 perf_testing = true;
432
433 } else if (strcmp(argv[i], "--quiet") == 0) {
434 verbose = false;
435 progress = false;
436
437 } else if (strcmp(argv[i], "--no_progress") == 0) {
438 progress = false;
439
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000440 } else if (strcmp(argv[i], "--raw_output") == 0) {
441 raw_output = true;
442
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000443 } else if (strcmp(argv[i], "--debug_file") == 0) {
ajm@google.com808e0e02011-08-03 21:08:51 +0000444 i++;
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000445 ASSERT_LT(i, argc) << "Specify filename after --debug_file";
ivocd66b44d2016-01-15 03:06:36 -0800446 ASSERT_EQ(apm->kNoError, apm->StartDebugRecording(argv[i], -1));
niklase@google.com470e71d2011-07-07 08:21:25 +0000447 } else {
448 FAIL() << "Unrecognized argument " << argv[i];
449 }
450 }
Bjorn Volckerbeb97982015-04-28 13:52:50 +0200451 apm->SetExtraOptions(config);
452
ajm@google.com808e0e02011-08-03 21:08:51 +0000453 // If we're reading a protobuf file, ensure a simulation hasn't also
454 // been requested (which makes no sense...)
455 ASSERT_FALSE(pb_filename && simulating);
niklase@google.com470e71d2011-07-07 08:21:25 +0000456
457 if (verbose) {
458 printf("Sample rate: %d Hz\n", sample_rate_hz);
Peter Kasting69558702016-01-12 16:26:35 -0800459 printf("Primary channels: %" PRIuS " (in), %" PRIuS " (out)\n",
niklase@google.com470e71d2011-07-07 08:21:25 +0000460 num_capture_input_channels,
461 num_capture_output_channels);
Peter Kasting69558702016-01-12 16:26:35 -0800462 printf("Reverse channels: %" PRIuS "\n", num_render_channels);
niklase@google.com470e71d2011-07-07 08:21:25 +0000463 }
464
kjellander@webrtc.org10abe252012-12-17 18:28:07 +0000465 const std::string out_path = webrtc::test::OutputPath();
niklase@google.com470e71d2011-07-07 08:21:25 +0000466 const char far_file_default[] = "apm_far.pcm";
467 const char near_file_default[] = "apm_near.pcm";
niklase@google.com470e71d2011-07-07 08:21:25 +0000468 const char event_filename[] = "apm_event.dat";
469 const char delay_filename[] = "apm_delay.dat";
470 const char drift_filename[] = "apm_drift.dat";
kjellander@webrtc.org10abe252012-12-17 18:28:07 +0000471 const std::string vad_file_default = out_path + "vad_out.dat";
472 const std::string ns_prob_file_default = out_path + "ns_prob.dat";
niklase@google.com470e71d2011-07-07 08:21:25 +0000473
474 if (!simulating) {
475 far_filename = far_file_default;
476 near_filename = near_file_default;
477 }
478
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000479 if (out_filename.size() == 0) {
480 out_filename = out_path + "out";
niklase@google.com470e71d2011-07-07 08:21:25 +0000481 }
482
ajm@google.com808e0e02011-08-03 21:08:51 +0000483 if (!vad_out_filename) {
kjellander@webrtc.org10abe252012-12-17 18:28:07 +0000484 vad_out_filename = vad_file_default.c_str();
niklase@google.com470e71d2011-07-07 08:21:25 +0000485 }
486
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000487 if (!ns_prob_filename) {
kjellander@webrtc.org10abe252012-12-17 18:28:07 +0000488 ns_prob_filename = ns_prob_file_default.c_str();
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000489 }
490
ajm@google.com808e0e02011-08-03 21:08:51 +0000491 FILE* pb_file = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000492 FILE* far_file = NULL;
493 FILE* near_file = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000494 FILE* event_file = NULL;
495 FILE* delay_file = NULL;
496 FILE* drift_file = NULL;
497 FILE* vad_out_file = NULL;
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000498 FILE* ns_prob_file = NULL;
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000499 FILE* aecm_echo_path_in_file = NULL;
500 FILE* aecm_echo_path_out_file = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000501
kwiberg62eaacf2016-02-17 06:39:05 -0800502 std::unique_ptr<WavWriter> output_wav_file;
503 std::unique_ptr<RawFile> output_raw_file;
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000504
ajm@google.com808e0e02011-08-03 21:08:51 +0000505 if (pb_filename) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000506 pb_file = OpenFile(pb_filename, "rb");
ajm@google.com808e0e02011-08-03 21:08:51 +0000507 } else {
508 if (far_filename) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000509 far_file = OpenFile(far_filename, "rb");
ajm@google.com808e0e02011-08-03 21:08:51 +0000510 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000511
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000512 near_file = OpenFile(near_filename, "rb");
ajm@google.com808e0e02011-08-03 21:08:51 +0000513 if (!simulating) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000514 event_file = OpenFile(event_filename, "rb");
515 delay_file = OpenFile(delay_filename, "rb");
516 drift_file = OpenFile(drift_filename, "rb");
ajm@google.com808e0e02011-08-03 21:08:51 +0000517 }
518 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000519
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000520 int near_size_bytes = 0;
ajm@google.com808e0e02011-08-03 21:08:51 +0000521 if (pb_file) {
522 struct stat st;
523 stat(pb_filename, &st);
524 // Crude estimate, but should be good enough.
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000525 near_size_bytes = st.st_size / 3;
ajm@google.com808e0e02011-08-03 21:08:51 +0000526 } else {
527 struct stat st;
528 stat(near_filename, &st);
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000529 near_size_bytes = st.st_size;
niklase@google.com470e71d2011-07-07 08:21:25 +0000530 }
531
532 if (apm->voice_detection()->is_enabled()) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000533 vad_out_file = OpenFile(vad_out_filename, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000534 }
535
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000536 if (apm->noise_suppression()->is_enabled()) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000537 ns_prob_file = OpenFile(ns_prob_filename, "wb");
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000538 }
539
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000540 if (aecm_echo_path_in_filename != NULL) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000541 aecm_echo_path_in_file = OpenFile(aecm_echo_path_in_filename, "rb");
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000542
ajm@google.com22e65152011-07-18 18:03:01 +0000543 const size_t path_size =
544 apm->echo_control_mobile()->echo_path_size_bytes();
kwiberg62eaacf2016-02-17 06:39:05 -0800545 std::unique_ptr<char[]> echo_path(new char[path_size]);
andrew@webrtc.org3119ecf2011-11-01 17:00:18 +0000546 ASSERT_EQ(path_size, fread(echo_path.get(),
547 sizeof(char),
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000548 path_size,
549 aecm_echo_path_in_file));
550 EXPECT_EQ(apm->kNoError,
andrew@webrtc.org3119ecf2011-11-01 17:00:18 +0000551 apm->echo_control_mobile()->SetEchoPath(echo_path.get(),
552 path_size));
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000553 fclose(aecm_echo_path_in_file);
554 aecm_echo_path_in_file = NULL;
555 }
556
557 if (aecm_echo_path_out_filename != NULL) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000558 aecm_echo_path_out_file = OpenFile(aecm_echo_path_out_filename, "wb");
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000559 }
560
niklase@google.com470e71d2011-07-07 08:21:25 +0000561 size_t read_count = 0;
562 int reverse_count = 0;
563 int primary_count = 0;
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000564 int near_read_bytes = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000565 TickInterval acc_ticks;
566
567 AudioFrame far_frame;
niklase@google.com470e71d2011-07-07 08:21:25 +0000568 AudioFrame near_frame;
niklase@google.com470e71d2011-07-07 08:21:25 +0000569
570 int delay_ms = 0;
571 int drift_samples = 0;
572 int capture_level = 127;
573 int8_t stream_has_voice = 0;
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000574 float ns_speech_prob = 0.0f;
niklase@google.com470e71d2011-07-07 08:21:25 +0000575
576 TickTime t0 = TickTime::Now();
577 TickTime t1 = t0;
pbos@webrtc.orgb7192b82013-04-10 07:50:54 +0000578 int64_t max_time_us = 0;
579 int64_t max_time_reverse_us = 0;
580 int64_t min_time_us = 1e6;
581 int64_t min_time_reverse_us = 1e6;
niklase@google.com470e71d2011-07-07 08:21:25 +0000582
ajm@google.com808e0e02011-08-03 21:08:51 +0000583 // TODO(ajm): Ideally we would refactor this block into separate functions,
584 // but for now we want to share the variables.
585 if (pb_file) {
586 Event event_msg;
kwiberg62eaacf2016-02-17 06:39:05 -0800587 std::unique_ptr<ChannelBuffer<float> > reverse_cb;
588 std::unique_ptr<ChannelBuffer<float> > primary_cb;
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000589 int output_sample_rate = 32000;
590 AudioProcessing::ChannelLayout output_layout = AudioProcessing::kMono;
ajm@google.com808e0e02011-08-03 21:08:51 +0000591 while (ReadMessageFromFile(pb_file, &event_msg)) {
592 std::ostringstream trace_stream;
593 trace_stream << "Processed frames: " << reverse_count << " (reverse), "
594 << primary_count << " (primary)";
595 SCOPED_TRACE(trace_stream.str());
niklase@google.com470e71d2011-07-07 08:21:25 +0000596
ajm@google.com808e0e02011-08-03 21:08:51 +0000597 if (event_msg.type() == Event::INIT) {
598 ASSERT_TRUE(event_msg.has_init());
599 const Init msg = event_msg.init();
niklase@google.com470e71d2011-07-07 08:21:25 +0000600
ajm@google.com808e0e02011-08-03 21:08:51 +0000601 ASSERT_TRUE(msg.has_sample_rate());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000602 ASSERT_TRUE(msg.has_num_input_channels());
603 ASSERT_TRUE(msg.has_num_output_channels());
604 ASSERT_TRUE(msg.has_num_reverse_channels());
605 int reverse_sample_rate = msg.sample_rate();
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000606 if (msg.has_reverse_sample_rate()) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000607 reverse_sample_rate = msg.reverse_sample_rate();
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000608 }
609 output_sample_rate = msg.sample_rate();
610 if (msg.has_output_sample_rate()) {
611 output_sample_rate = msg.output_sample_rate();
612 }
Peter Kasting69558702016-01-12 16:26:35 -0800613 output_layout =
614 LayoutFromChannels(static_cast<size_t>(msg.num_output_channels()));
615 ASSERT_EQ(kNoErr,
616 apm->Initialize(
617 msg.sample_rate(),
618 output_sample_rate,
619 reverse_sample_rate,
620 LayoutFromChannels(
621 static_cast<size_t>(msg.num_input_channels())),
622 output_layout,
623 LayoutFromChannels(
624 static_cast<size_t>(msg.num_reverse_channels()))));
ajm@google.com808e0e02011-08-03 21:08:51 +0000625
626 samples_per_channel = msg.sample_rate() / 100;
bjornv@webrtc.orgee300822014-11-13 11:00:10 +0000627 far_frame.sample_rate_hz_ = reverse_sample_rate;
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000628 far_frame.samples_per_channel_ = reverse_sample_rate / 100;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000629 far_frame.num_channels_ = msg.num_reverse_channels();
630 near_frame.sample_rate_hz_ = msg.sample_rate();
631 near_frame.samples_per_channel_ = samples_per_channel;
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000632 near_frame.num_channels_ = msg.num_input_channels();
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000633 reverse_cb.reset(new ChannelBuffer<float>(
634 far_frame.samples_per_channel_,
635 msg.num_reverse_channels()));
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000636 primary_cb.reset(new ChannelBuffer<float>(samples_per_channel,
637 msg.num_input_channels()));
ajm@google.com808e0e02011-08-03 21:08:51 +0000638
639 if (verbose) {
640 printf("Init at frame: %d (primary), %d (reverse)\n",
641 primary_count, reverse_count);
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000642 printf(" Primary rates: %d Hz (in), %d Hz (out)\n",
643 msg.sample_rate(), output_sample_rate);
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000644 printf(" Primary channels: %d (in), %d (out)\n",
645 msg.num_input_channels(),
646 msg.num_output_channels());
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000647 printf(" Reverse rate: %d\n", reverse_sample_rate);
648 printf(" Reverse channels: %d\n", msg.num_reverse_channels());
ajm@google.com808e0e02011-08-03 21:08:51 +0000649 }
650
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000651 if (!raw_output) {
aluebsb0ad43b2015-11-20 00:11:53 -0800652 // The WAV file needs to be reset every time, because it can't change
653 // its sample rate or number of channels.
Peter Kasting69558702016-01-12 16:26:35 -0800654 output_wav_file.reset(new WavWriter(
655 out_filename + ".wav", output_sample_rate,
656 static_cast<size_t>(msg.num_output_channels())));
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000657 }
658
ajm@google.com808e0e02011-08-03 21:08:51 +0000659 } else if (event_msg.type() == Event::REVERSE_STREAM) {
660 ASSERT_TRUE(event_msg.has_reverse_stream());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000661 ReverseStream msg = event_msg.reverse_stream();
ajm@google.com808e0e02011-08-03 21:08:51 +0000662 reverse_count++;
663
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000664 ASSERT_TRUE(msg.has_data() ^ (msg.channel_size() > 0));
665 if (msg.has_data()) {
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000666 ASSERT_EQ(sizeof(int16_t) * far_frame.samples_per_channel_ *
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000667 far_frame.num_channels_, msg.data().size());
668 memcpy(far_frame.data_, msg.data().data(), msg.data().size());
669 } else {
670 for (int i = 0; i < msg.channel_size(); ++i) {
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +0000671 memcpy(reverse_cb->channels()[i],
672 msg.channel(i).data(),
673 reverse_cb->num_frames() *
674 sizeof(reverse_cb->channels()[i][0]));
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000675 }
676 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000677
678 if (perf_testing) {
679 t0 = TickTime::Now();
680 }
681
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000682 if (msg.has_data()) {
683 ASSERT_EQ(apm->kNoError,
aluebsb0319552016-03-17 20:39:53 -0700684 apm->ProcessReverseStream(&far_frame));
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000685 } else {
686 ASSERT_EQ(apm->kNoError,
687 apm->AnalyzeReverseStream(
688 reverse_cb->channels(),
689 far_frame.samples_per_channel_,
690 far_frame.sample_rate_hz_,
691 LayoutFromChannels(far_frame.num_channels_)));
692 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000693
694 if (perf_testing) {
695 t1 = TickTime::Now();
696 TickInterval tick_diff = t1 - t0;
697 acc_ticks += tick_diff;
698 if (tick_diff.Microseconds() > max_time_reverse_us) {
699 max_time_reverse_us = tick_diff.Microseconds();
700 }
701 if (tick_diff.Microseconds() < min_time_reverse_us) {
702 min_time_reverse_us = tick_diff.Microseconds();
703 }
704 }
705
706 } else if (event_msg.type() == Event::STREAM) {
707 ASSERT_TRUE(event_msg.has_stream());
708 const Stream msg = event_msg.stream();
709 primary_count++;
710
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000711 // ProcessStream could have changed this for the output frame.
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000712 near_frame.num_channels_ = apm->num_input_channels();
ajm@google.com808e0e02011-08-03 21:08:51 +0000713
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000714 ASSERT_TRUE(msg.has_input_data() ^ (msg.input_channel_size() > 0));
715 if (msg.has_input_data()) {
716 ASSERT_EQ(sizeof(int16_t) * samples_per_channel *
717 near_frame.num_channels_, msg.input_data().size());
718 memcpy(near_frame.data_,
719 msg.input_data().data(),
720 msg.input_data().size());
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000721 near_read_bytes += msg.input_data().size();
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000722 } else {
723 for (int i = 0; i < msg.input_channel_size(); ++i) {
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +0000724 memcpy(primary_cb->channels()[i],
725 msg.input_channel(i).data(),
726 primary_cb->num_frames() *
727 sizeof(primary_cb->channels()[i][0]));
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000728 near_read_bytes += msg.input_channel(i).size();
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000729 }
730 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000731
ajm@google.com808e0e02011-08-03 21:08:51 +0000732 if (progress && primary_count % 100 == 0) {
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000733 near_read_bytes = std::min(near_read_bytes, near_size_bytes);
ajm@google.com808e0e02011-08-03 21:08:51 +0000734 printf("%.0f%% complete\r",
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000735 (near_read_bytes * 100.0) / near_size_bytes);
ajm@google.com808e0e02011-08-03 21:08:51 +0000736 fflush(stdout);
737 }
738
739 if (perf_testing) {
740 t0 = TickTime::Now();
741 }
742
743 ASSERT_EQ(apm->kNoError,
744 apm->gain_control()->set_stream_analog_level(msg.level()));
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000745 delay_ms = msg.delay() + extra_delay_ms;
746 if (override_delay_ms) {
747 delay_ms = override_delay_ms;
748 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000749 ASSERT_EQ(apm->kNoError,
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000750 apm->set_stream_delay_ms(delay_ms));
andrew@webrtc.org6be1e932013-03-01 18:47:28 +0000751 apm->echo_cancellation()->set_stream_drift_samples(msg.drift());
ajm@google.com808e0e02011-08-03 21:08:51 +0000752
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +0000753 if (msg.has_keypress()) {
754 apm->set_stream_key_pressed(msg.keypress());
755 } else {
756 apm->set_stream_key_pressed(true);
757 }
758
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000759 int err = apm->kNoError;
760 if (msg.has_input_data()) {
761 err = apm->ProcessStream(&near_frame);
762 ASSERT_TRUE(near_frame.num_channels_ == apm->num_output_channels());
763 } else {
764 err = apm->ProcessStream(
765 primary_cb->channels(),
766 near_frame.samples_per_channel_,
767 near_frame.sample_rate_hz_,
768 LayoutFromChannels(near_frame.num_channels_),
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000769 output_sample_rate,
770 output_layout,
771 primary_cb->channels());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000772 }
773
ajm@google.com808e0e02011-08-03 21:08:51 +0000774 if (err == apm->kBadStreamParameterWarning) {
775 printf("Bad parameter warning. %s\n", trace_stream.str().c_str());
776 }
777 ASSERT_TRUE(err == apm->kNoError ||
778 err == apm->kBadStreamParameterWarning);
779
ajm@google.com808e0e02011-08-03 21:08:51 +0000780 stream_has_voice =
781 static_cast<int8_t>(apm->voice_detection()->stream_has_voice());
782 if (vad_out_file != NULL) {
783 ASSERT_EQ(1u, fwrite(&stream_has_voice,
784 sizeof(stream_has_voice),
785 1,
786 vad_out_file));
787 }
788
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000789 if (ns_prob_file != NULL) {
790 ns_speech_prob = apm->noise_suppression()->speech_probability();
791 ASSERT_EQ(1u, fwrite(&ns_speech_prob,
792 sizeof(ns_speech_prob),
793 1,
794 ns_prob_file));
795 }
796
ajm@google.com808e0e02011-08-03 21:08:51 +0000797 if (perf_testing) {
798 t1 = TickTime::Now();
799 TickInterval tick_diff = t1 - t0;
800 acc_ticks += tick_diff;
801 if (tick_diff.Microseconds() > max_time_us) {
802 max_time_us = tick_diff.Microseconds();
803 }
804 if (tick_diff.Microseconds() < min_time_us) {
805 min_time_us = tick_diff.Microseconds();
806 }
807 }
808
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000809 const size_t samples_per_channel = output_sample_rate / 100;
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000810 if (msg.has_input_data()) {
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000811 if (raw_output && !output_raw_file) {
812 output_raw_file.reset(new RawFile(out_filename + ".pcm"));
813 }
814 WriteIntData(near_frame.data_,
815 apm->num_output_channels() * samples_per_channel,
816 output_wav_file.get(),
817 output_raw_file.get());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000818 } else {
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000819 if (raw_output && !output_raw_file) {
820 output_raw_file.reset(new RawFile(out_filename + ".float"));
821 }
822 WriteFloatData(primary_cb->channels(),
823 samples_per_channel,
824 apm->num_output_channels(),
825 output_wav_file.get(),
826 output_raw_file.get());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000827 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000828 }
829 }
830
831 ASSERT_TRUE(feof(pb_file));
ajm@google.com808e0e02011-08-03 21:08:51 +0000832
833 } else {
bjornv@google.coma2c6ea02011-09-27 08:04:45 +0000834 enum Events {
835 kInitializeEvent,
836 kRenderEvent,
837 kCaptureEvent,
838 kResetEventDeprecated
839 };
840 int16_t event = 0;
ajm@google.com808e0e02011-08-03 21:08:51 +0000841 while (simulating || feof(event_file) == 0) {
842 std::ostringstream trace_stream;
843 trace_stream << "Processed frames: " << reverse_count << " (reverse), "
844 << primary_count << " (primary)";
845 SCOPED_TRACE(trace_stream.str());
846
847 if (simulating) {
848 if (far_file == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000849 event = kCaptureEvent;
850 } else {
peah58cf5f12016-02-16 07:26:21 -0800851 event = (event == kCaptureEvent) ? kRenderEvent : kCaptureEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000852 }
853 } else {
ajm@google.com808e0e02011-08-03 21:08:51 +0000854 read_count = fread(&event, sizeof(event), 1, event_file);
855 if (read_count != 1) {
856 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000857 }
858 }
859
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000860 far_frame.sample_rate_hz_ = sample_rate_hz;
861 far_frame.samples_per_channel_ = samples_per_channel;
862 far_frame.num_channels_ = num_render_channels;
863 near_frame.sample_rate_hz_ = sample_rate_hz;
864 near_frame.samples_per_channel_ = samples_per_channel;
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000865
ajm@google.com808e0e02011-08-03 21:08:51 +0000866 if (event == kInitializeEvent || event == kResetEventDeprecated) {
867 ASSERT_EQ(1u,
868 fread(&sample_rate_hz, sizeof(sample_rate_hz), 1, event_file));
869 samples_per_channel = sample_rate_hz / 100;
niklase@google.com470e71d2011-07-07 08:21:25 +0000870
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000871 int32_t unused_device_sample_rate_hz;
ajm@google.com808e0e02011-08-03 21:08:51 +0000872 ASSERT_EQ(1u,
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000873 fread(&unused_device_sample_rate_hz,
874 sizeof(unused_device_sample_rate_hz),
ajm@google.com808e0e02011-08-03 21:08:51 +0000875 1,
876 event_file));
877
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000878 ASSERT_EQ(kNoErr, apm->Initialize(
879 sample_rate_hz,
880 sample_rate_hz,
881 sample_rate_hz,
882 LayoutFromChannels(num_capture_input_channels),
883 LayoutFromChannels(num_capture_output_channels),
884 LayoutFromChannels(num_render_channels)));
ajm@google.com808e0e02011-08-03 21:08:51 +0000885
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000886 far_frame.sample_rate_hz_ = sample_rate_hz;
887 far_frame.samples_per_channel_ = samples_per_channel;
888 far_frame.num_channels_ = num_render_channels;
889 near_frame.sample_rate_hz_ = sample_rate_hz;
890 near_frame.samples_per_channel_ = samples_per_channel;
ajm@google.com808e0e02011-08-03 21:08:51 +0000891
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000892 if (!raw_output) {
bjornv@webrtc.org634c9262014-09-24 12:21:51 +0000893 // The WAV file needs to be reset every time, because it can't change
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000894 // it's sample rate or number of channels.
andrew@webrtc.orga3ed7132014-10-31 21:51:03 +0000895 output_wav_file.reset(new WavWriter(out_filename + ".wav",
896 sample_rate_hz,
897 num_capture_output_channels));
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000898 }
899
ajm@google.com808e0e02011-08-03 21:08:51 +0000900 if (verbose) {
901 printf("Init at frame: %d (primary), %d (reverse)\n",
902 primary_count, reverse_count);
903 printf(" Sample rate: %d Hz\n", sample_rate_hz);
904 }
905
906 } else if (event == kRenderEvent) {
907 reverse_count++;
ajm@google.com808e0e02011-08-03 21:08:51 +0000908
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000909 size_t size = samples_per_channel * num_render_channels;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000910 read_count = fread(far_frame.data_,
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000911 sizeof(int16_t),
912 size,
ajm@google.com808e0e02011-08-03 21:08:51 +0000913 far_file);
914
915 if (simulating) {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000916 if (read_count != size) {
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000917 // Read an equal amount from the near file to avoid errors due to
918 // not reaching end-of-file.
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000919 EXPECT_EQ(0, fseek(near_file, read_count * sizeof(int16_t),
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000920 SEEK_CUR));
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700921 break; // This is expected.
ajm@google.com808e0e02011-08-03 21:08:51 +0000922 }
923 } else {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000924 ASSERT_EQ(size, read_count);
ajm@google.com808e0e02011-08-03 21:08:51 +0000925 }
926
927 if (perf_testing) {
928 t0 = TickTime::Now();
929 }
930
931 ASSERT_EQ(apm->kNoError,
aluebsb0319552016-03-17 20:39:53 -0700932 apm->ProcessReverseStream(&far_frame));
ajm@google.com808e0e02011-08-03 21:08:51 +0000933
934 if (perf_testing) {
935 t1 = TickTime::Now();
936 TickInterval tick_diff = t1 - t0;
937 acc_ticks += tick_diff;
938 if (tick_diff.Microseconds() > max_time_reverse_us) {
939 max_time_reverse_us = tick_diff.Microseconds();
940 }
941 if (tick_diff.Microseconds() < min_time_reverse_us) {
942 min_time_reverse_us = tick_diff.Microseconds();
943 }
944 }
945
946 } else if (event == kCaptureEvent) {
947 primary_count++;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000948 near_frame.num_channels_ = num_capture_input_channels;
ajm@google.com808e0e02011-08-03 21:08:51 +0000949
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000950 size_t size = samples_per_channel * num_capture_input_channels;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000951 read_count = fread(near_frame.data_,
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000952 sizeof(int16_t),
953 size,
ajm@google.com808e0e02011-08-03 21:08:51 +0000954 near_file);
955
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000956 near_read_bytes += read_count * sizeof(int16_t);
ajm@google.com808e0e02011-08-03 21:08:51 +0000957 if (progress && primary_count % 100 == 0) {
958 printf("%.0f%% complete\r",
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000959 (near_read_bytes * 100.0) / near_size_bytes);
ajm@google.com808e0e02011-08-03 21:08:51 +0000960 fflush(stdout);
961 }
962 if (simulating) {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000963 if (read_count != size) {
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700964 break; // This is expected.
ajm@google.com808e0e02011-08-03 21:08:51 +0000965 }
966
967 delay_ms = 0;
968 drift_samples = 0;
969 } else {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000970 ASSERT_EQ(size, read_count);
ajm@google.com808e0e02011-08-03 21:08:51 +0000971
972 // TODO(ajm): sizeof(delay_ms) for current files?
973 ASSERT_EQ(1u,
974 fread(&delay_ms, 2, 1, delay_file));
975 ASSERT_EQ(1u,
976 fread(&drift_samples, sizeof(drift_samples), 1, drift_file));
977 }
978
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000979 if (apm->gain_control()->is_enabled() &&
980 apm->gain_control()->mode() == GainControl::kAdaptiveAnalog) {
andrew@webrtc.org81865342012-10-27 00:28:27 +0000981 SimulateMic(capture_level, &near_frame);
982 }
983
ajm@google.com808e0e02011-08-03 21:08:51 +0000984 if (perf_testing) {
985 t0 = TickTime::Now();
986 }
987
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000988 const int capture_level_in = capture_level;
ajm@google.com808e0e02011-08-03 21:08:51 +0000989 ASSERT_EQ(apm->kNoError,
990 apm->gain_control()->set_stream_analog_level(capture_level));
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000991 delay_ms += extra_delay_ms;
992 if (override_delay_ms) {
993 delay_ms = override_delay_ms;
994 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000995 ASSERT_EQ(apm->kNoError,
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000996 apm->set_stream_delay_ms(delay_ms));
andrew@webrtc.org6be1e932013-03-01 18:47:28 +0000997 apm->echo_cancellation()->set_stream_drift_samples(drift_samples);
ajm@google.com808e0e02011-08-03 21:08:51 +0000998
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +0000999 apm->set_stream_key_pressed(true);
1000
ajm@google.com808e0e02011-08-03 21:08:51 +00001001 int err = apm->ProcessStream(&near_frame);
1002 if (err == apm->kBadStreamParameterWarning) {
1003 printf("Bad parameter warning. %s\n", trace_stream.str().c_str());
1004 }
1005 ASSERT_TRUE(err == apm->kNoError ||
1006 err == apm->kBadStreamParameterWarning);
andrew@webrtc.org63a50982012-05-02 23:56:37 +00001007 ASSERT_TRUE(near_frame.num_channels_ == apm->num_output_channels());
ajm@google.com808e0e02011-08-03 21:08:51 +00001008
1009 capture_level = apm->gain_control()->stream_analog_level();
1010
1011 stream_has_voice =
1012 static_cast<int8_t>(apm->voice_detection()->stream_has_voice());
1013 if (vad_out_file != NULL) {
1014 ASSERT_EQ(1u, fwrite(&stream_has_voice,
1015 sizeof(stream_has_voice),
1016 1,
1017 vad_out_file));
1018 }
1019
bjornv@webrtc.org08329f42012-07-12 21:00:43 +00001020 if (ns_prob_file != NULL) {
1021 ns_speech_prob = apm->noise_suppression()->speech_probability();
1022 ASSERT_EQ(1u, fwrite(&ns_speech_prob,
1023 sizeof(ns_speech_prob),
1024 1,
1025 ns_prob_file));
1026 }
1027
ajm@google.com808e0e02011-08-03 21:08:51 +00001028 if (apm->gain_control()->mode() != GainControl::kAdaptiveAnalog) {
1029 ASSERT_EQ(capture_level_in, capture_level);
1030 }
1031
1032 if (perf_testing) {
1033 t1 = TickTime::Now();
1034 TickInterval tick_diff = t1 - t0;
1035 acc_ticks += tick_diff;
1036 if (tick_diff.Microseconds() > max_time_us) {
1037 max_time_us = tick_diff.Microseconds();
1038 }
1039 if (tick_diff.Microseconds() < min_time_us) {
1040 min_time_us = tick_diff.Microseconds();
1041 }
1042 }
1043
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +00001044 if (raw_output && !output_raw_file) {
1045 output_raw_file.reset(new RawFile(out_filename + ".pcm"));
1046 }
bjornv@webrtc.org634c9262014-09-24 12:21:51 +00001047 if (!raw_output && !output_wav_file) {
andrew@webrtc.orga3ed7132014-10-31 21:51:03 +00001048 output_wav_file.reset(new WavWriter(out_filename + ".wav",
1049 sample_rate_hz,
1050 num_capture_output_channels));
bjornv@webrtc.org634c9262014-09-24 12:21:51 +00001051 }
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +00001052 WriteIntData(near_frame.data_,
1053 size,
1054 output_wav_file.get(),
1055 output_raw_file.get());
Andrew MacDonaldcb05b722015-05-07 22:17:51 -07001056 } else {
ajm@google.com808e0e02011-08-03 21:08:51 +00001057 FAIL() << "Event " << event << " is unrecognized";
niklase@google.com470e71d2011-07-07 08:21:25 +00001058 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001059 }
1060 }
peahc1cd2bb2015-11-09 10:38:07 -08001061 if (progress) {
1062 printf("100%% complete\r");
1063 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001064
bjornv@google.comc4b939c2011-07-13 08:09:56 +00001065 if (aecm_echo_path_out_file != NULL) {
ajm@google.com22e65152011-07-18 18:03:01 +00001066 const size_t path_size =
1067 apm->echo_control_mobile()->echo_path_size_bytes();
kwiberg62eaacf2016-02-17 06:39:05 -08001068 std::unique_ptr<char[]> echo_path(new char[path_size]);
andrew@webrtc.org3119ecf2011-11-01 17:00:18 +00001069 apm->echo_control_mobile()->GetEchoPath(echo_path.get(), path_size);
1070 ASSERT_EQ(path_size, fwrite(echo_path.get(),
1071 sizeof(char),
bjornv@google.comc4b939c2011-07-13 08:09:56 +00001072 path_size,
1073 aecm_echo_path_out_file));
1074 fclose(aecm_echo_path_out_file);
1075 aecm_echo_path_out_file = NULL;
1076 }
1077
niklase@google.com470e71d2011-07-07 08:21:25 +00001078 if (verbose) {
1079 printf("\nProcessed frames: %d (primary), %d (reverse)\n",
1080 primary_count, reverse_count);
andrew@webrtc.org94c74132011-09-19 15:17:57 +00001081
andrew@webrtc.org755b04a2011-11-15 16:57:56 +00001082 if (apm->level_estimator()->is_enabled()) {
1083 printf("\n--Level metrics--\n");
1084 printf("RMS: %d dBFS\n", -apm->level_estimator()->RMS());
1085 }
andrew@webrtc.org94c74132011-09-19 15:17:57 +00001086 if (apm->echo_cancellation()->are_metrics_enabled()) {
1087 EchoCancellation::Metrics metrics;
1088 apm->echo_cancellation()->GetMetrics(&metrics);
1089 printf("\n--Echo metrics--\n");
1090 printf("(avg, max, min)\n");
1091 printf("ERL: ");
1092 PrintStat(metrics.echo_return_loss);
1093 printf("ERLE: ");
1094 PrintStat(metrics.echo_return_loss_enhancement);
1095 printf("ANLP: ");
1096 PrintStat(metrics.a_nlp);
1097 }
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +00001098 if (apm->echo_cancellation()->is_delay_logging_enabled()) {
1099 int median = 0;
1100 int std = 0;
bjornv@webrtc.orgb1786db2015-02-03 06:06:26 +00001101 float fraction_poor_delays = 0;
1102 apm->echo_cancellation()->GetDelayMetrics(&median, &std,
1103 &fraction_poor_delays);
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +00001104 printf("\n--Delay metrics--\n");
1105 printf("Median: %3d\n", median);
1106 printf("Standard deviation: %3d\n", std);
bjornv@webrtc.orgb1786db2015-02-03 06:06:26 +00001107 printf("Poor delay values: %3.1f%%\n", fraction_poor_delays * 100);
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +00001108 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001109 }
1110
ajm@google.com808e0e02011-08-03 21:08:51 +00001111 if (!pb_file) {
1112 int8_t temp_int8;
1113 if (far_file) {
1114 read_count = fread(&temp_int8, sizeof(temp_int8), 1, far_file);
1115 EXPECT_NE(0, feof(far_file)) << "Far-end file not fully processed";
1116 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001117
ajm@google.com808e0e02011-08-03 21:08:51 +00001118 read_count = fread(&temp_int8, sizeof(temp_int8), 1, near_file);
1119 EXPECT_NE(0, feof(near_file)) << "Near-end file not fully processed";
1120
1121 if (!simulating) {
1122 read_count = fread(&temp_int8, sizeof(temp_int8), 1, event_file);
1123 EXPECT_NE(0, feof(event_file)) << "Event file not fully processed";
1124 read_count = fread(&temp_int8, sizeof(temp_int8), 1, delay_file);
1125 EXPECT_NE(0, feof(delay_file)) << "Delay file not fully processed";
1126 read_count = fread(&temp_int8, sizeof(temp_int8), 1, drift_file);
1127 EXPECT_NE(0, feof(drift_file)) << "Drift file not fully processed";
1128 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001129 }
1130
1131 if (perf_testing) {
1132 if (primary_count > 0) {
pbos@webrtc.orgb7192b82013-04-10 07:50:54 +00001133 int64_t exec_time = acc_ticks.Milliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +00001134 printf("\nTotal time: %.3f s, file time: %.2f s\n",
1135 exec_time * 0.001, primary_count * 0.01);
1136 printf("Time per frame: %.3f ms (average), %.3f ms (max),"
1137 " %.3f ms (min)\n",
1138 (exec_time * 1.0) / primary_count,
1139 (max_time_us + max_time_reverse_us) / 1000.0,
1140 (min_time_us + min_time_reverse_us) / 1000.0);
kma@webrtc.org0e739502012-12-07 15:26:28 +00001141 // Record the results with Perf test tools.
kjellander@webrtc.org00ab7cf2013-02-11 12:33:03 +00001142 webrtc::test::PrintResult("audioproc", "", "time_per_10ms_frame",
kma@webrtc.org0e739502012-12-07 15:26:28 +00001143 (exec_time * 1000) / primary_count, "us", false);
niklase@google.com470e71d2011-07-07 08:21:25 +00001144 } else {
1145 printf("Warning: no capture frames\n");
1146 }
1147 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001148}
andrew@webrtc.orga8b97372014-03-10 22:26:12 +00001149
ajm@google.com808e0e02011-08-03 21:08:51 +00001150} // namespace
andrew@webrtc.orga8b97372014-03-10 22:26:12 +00001151} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +00001152
Andrew MacDonaldcb05b722015-05-07 22:17:51 -07001153int main(int argc, char* argv[]) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +00001154 webrtc::void_main(argc, argv);
niklase@google.com470e71d2011-07-07 08:21:25 +00001155
andrew@webrtc.org64235092011-08-19 21:22:08 +00001156 // Optional, but removes memory leak noise from Valgrind.
1157 google::protobuf::ShutdownProtobufLibrary();
niklase@google.com470e71d2011-07-07 08:21:25 +00001158 return 0;
1159}