blob: 6d5b97974a0e0cbc0b98a192cf0656b78f897bbe [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"
Niels Möllerd28db7f2016-05-10 16:31:47 +020022#include "webrtc/base/timeutils.h"
andrew@webrtc.org22858d42013-10-23 14:07:17 +000023#include "webrtc/common.h"
kma@webrtc.org0e739502012-12-07 15:26:28 +000024#include "webrtc/modules/audio_processing/include/audio_processing.h"
Andrew MacDonaldcb05b722015-05-07 22:17:51 -070025#include "webrtc/modules/audio_processing/test/protobuf_utils.h"
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000026#include "webrtc/modules/audio_processing/test/test_utils.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010027#include "webrtc/modules/include/module_common_types.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010028#include "webrtc/system_wrappers/include/cpu_features_wrapper.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");
peahca4cac72016-06-29 15:26:12 -0700111 printf(" --level_control\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000112 printf("\n");
113 printf("Modifiers:\n");
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000114 printf(" --noasm Disable SSE optimization.\n");
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000115 printf(" --add_delay DELAY Add DELAY ms to input value.\n");
116 printf(" --delay DELAY Override input delay with DELAY ms.\n");
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000117 printf(" --perf Measure performance.\n");
118 printf(" --quiet Suppress text output.\n");
119 printf(" --no_progress Suppress progress.\n");
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000120 printf(" --raw_output Raw output instead of WAV file.\n");
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000121 printf(" --debug_file FILE Dump a debug recording.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000122}
123
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000124static float MicLevel2Gain(int level) {
125 return pow(10.0f, ((level - 127.0f) / 128.0f * 40.0f) / 20.0f);
andrew@webrtc.org81865342012-10-27 00:28:27 +0000126}
127
128static void SimulateMic(int mic_level, AudioFrame* frame) {
129 mic_level = std::min(std::max(mic_level, 0), 255);
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000130 float mic_gain = MicLevel2Gain(mic_level);
andrew@webrtc.org81865342012-10-27 00:28:27 +0000131 int num_samples = frame->samples_per_channel_ * frame->num_channels_;
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000132 float v;
andrew@webrtc.org81865342012-10-27 00:28:27 +0000133 for (int n = 0; n < num_samples; n++) {
134 v = floor(frame->data_[n] * mic_gain + 0.5);
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000135 v = std::max(std::min(32767.0f, v), -32768.0f);
andrew@webrtc.org81865342012-10-27 00:28:27 +0000136 frame->data_[n] = static_cast<int16_t>(v);
137 }
138}
139
niklase@google.com470e71d2011-07-07 08:21:25 +0000140// void function for gtest.
141void void_main(int argc, char* argv[]) {
142 if (argc > 1 && strcmp(argv[1], "--help") == 0) {
143 usage();
144 return;
145 }
146
147 if (argc < 2) {
148 printf("Did you mean to run without arguments?\n");
149 printf("Try `process_test --help' for more information.\n\n");
150 }
151
kwiberg62eaacf2016-02-17 06:39:05 -0800152 std::unique_ptr<AudioProcessing> apm(AudioProcessing::Create());
andrew@webrtc.orgf3930e92013-09-18 22:37:32 +0000153 ASSERT_TRUE(apm.get() != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000154
ajm@google.com808e0e02011-08-03 21:08:51 +0000155 const char* pb_filename = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000156 const char* far_filename = NULL;
157 const char* near_filename = NULL;
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000158 std::string out_filename;
niklase@google.com470e71d2011-07-07 08:21:25 +0000159 const char* vad_out_filename = NULL;
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000160 const char* ns_prob_filename = NULL;
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000161 const char* aecm_echo_path_in_filename = NULL;
162 const char* aecm_echo_path_out_filename = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000163
164 int32_t sample_rate_hz = 16000;
niklase@google.com470e71d2011-07-07 08:21:25 +0000165
Peter Kasting69558702016-01-12 16:26:35 -0800166 size_t num_capture_input_channels = 1;
167 size_t num_capture_output_channels = 1;
168 size_t num_render_channels = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000169
170 int samples_per_channel = sample_rate_hz / 100;
171
172 bool simulating = false;
173 bool perf_testing = false;
174 bool verbose = true;
175 bool progress = true;
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000176 bool raw_output = false;
andrew@webrtc.org4b13fc92011-11-09 19:27:11 +0000177 int extra_delay_ms = 0;
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000178 int override_delay_ms = 0;
Bjorn Volckerbeb97982015-04-28 13:52:50 +0200179 Config config;
niklase@google.com470e71d2011-07-07 08:21:25 +0000180
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000181 ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(true));
niklase@google.com470e71d2011-07-07 08:21:25 +0000182 for (int i = 1; i < argc; i++) {
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000183 if (strcmp(argv[i], "-pb") == 0) {
ajm@google.com808e0e02011-08-03 21:08:51 +0000184 i++;
185 ASSERT_LT(i, argc) << "Specify protobuf filename after -pb";
186 pb_filename = argv[i];
187
188 } else if (strcmp(argv[i], "-ir") == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000189 i++;
190 ASSERT_LT(i, argc) << "Specify filename after -ir";
191 far_filename = argv[i];
192 simulating = true;
193
194 } else if (strcmp(argv[i], "-i") == 0) {
195 i++;
196 ASSERT_LT(i, argc) << "Specify filename after -i";
197 near_filename = argv[i];
198 simulating = true;
199
200 } else if (strcmp(argv[i], "-o") == 0) {
201 i++;
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000202 ASSERT_LT(i, argc) << "Specify filename without extension after -o";
niklase@google.com470e71d2011-07-07 08:21:25 +0000203 out_filename = argv[i];
204
205 } else if (strcmp(argv[i], "-fs") == 0) {
206 i++;
207 ASSERT_LT(i, argc) << "Specify sample rate after -fs";
208 ASSERT_EQ(1, sscanf(argv[i], "%d", &sample_rate_hz));
209 samples_per_channel = sample_rate_hz / 100;
210
niklase@google.com470e71d2011-07-07 08:21:25 +0000211 } else if (strcmp(argv[i], "-ch") == 0) {
212 i++;
213 ASSERT_LT(i + 1, argc) << "Specify number of channels after -ch";
Peter Kasting69558702016-01-12 16:26:35 -0800214 ASSERT_EQ(1, sscanf(argv[i], "%" PRIuS, &num_capture_input_channels));
niklase@google.com470e71d2011-07-07 08:21:25 +0000215 i++;
Peter Kasting69558702016-01-12 16:26:35 -0800216 ASSERT_EQ(1, sscanf(argv[i], "%" PRIuS, &num_capture_output_channels));
niklase@google.com470e71d2011-07-07 08:21:25 +0000217
niklase@google.com470e71d2011-07-07 08:21:25 +0000218 } else if (strcmp(argv[i], "-rch") == 0) {
219 i++;
220 ASSERT_LT(i, argc) << "Specify number of channels after -rch";
Peter Kasting69558702016-01-12 16:26:35 -0800221 ASSERT_EQ(1, sscanf(argv[i], "%" PRIuS, &num_render_channels));
niklase@google.com470e71d2011-07-07 08:21:25 +0000222
niklase@google.com470e71d2011-07-07 08:21:25 +0000223 } else if (strcmp(argv[i], "-aec") == 0) {
224 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +0000225 ASSERT_EQ(apm->kNoError,
226 apm->echo_cancellation()->enable_metrics(true));
227 ASSERT_EQ(apm->kNoError,
228 apm->echo_cancellation()->enable_delay_logging(true));
niklase@google.com470e71d2011-07-07 08:21:25 +0000229
niklase@google.com470e71d2011-07-07 08:21:25 +0000230 } else if (strcmp(argv[i], "--drift_compensation") == 0) {
231 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
232 // TODO(ajm): this is enabled in the VQE test app by default. Investigate
233 // why it can give better performance despite passing zeros.
234 ASSERT_EQ(apm->kNoError,
235 apm->echo_cancellation()->enable_drift_compensation(true));
236 } else if (strcmp(argv[i], "--no_drift_compensation") == 0) {
237 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
238 ASSERT_EQ(apm->kNoError,
239 apm->echo_cancellation()->enable_drift_compensation(false));
240
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000241 } else if (strcmp(argv[i], "--no_echo_metrics") == 0) {
242 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
243 ASSERT_EQ(apm->kNoError,
244 apm->echo_cancellation()->enable_metrics(false));
245
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +0000246 } else if (strcmp(argv[i], "--no_delay_logging") == 0) {
247 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
248 ASSERT_EQ(apm->kNoError,
249 apm->echo_cancellation()->enable_delay_logging(false));
250
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000251 } else if (strcmp(argv[i], "--no_level_metrics") == 0) {
252 ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(false));
253
andrew@webrtc.orgdff69c52013-04-30 23:01:09 +0000254 } else if (strcmp(argv[i], "--aec_suppression_level") == 0) {
255 i++;
256 ASSERT_LT(i, argc) << "Specify level after --aec_suppression_level";
257 int suppression_level;
258 ASSERT_EQ(1, sscanf(argv[i], "%d", &suppression_level));
259 ASSERT_EQ(apm->kNoError,
260 apm->echo_cancellation()->set_suppression_level(
261 static_cast<webrtc::EchoCancellation::SuppressionLevel>(
262 suppression_level)));
263
peahca4cac72016-06-29 15:26:12 -0700264 } else if (strcmp(argv[i], "--level_control") == 0) {
265 config.Set<LevelControl>(new LevelControl(true));
266
andrew@webrtc.org22858d42013-10-23 14:07:17 +0000267 } else if (strcmp(argv[i], "--extended_filter") == 0) {
Henrik Lundin441f6342015-06-09 16:03:13 +0200268 config.Set<ExtendedFilter>(new ExtendedFilter(true));
andrew@webrtc.org22858d42013-10-23 14:07:17 +0000269
bjornv@webrtc.org84f8ec12014-06-19 12:14:33 +0000270 } else if (strcmp(argv[i], "--no_reported_delay") == 0) {
henrik.lundin0f133b92015-07-02 00:17:55 -0700271 config.Set<DelayAgnostic>(new DelayAgnostic(true));
272
273 } else if (strcmp(argv[i], "--delay_agnostic") == 0) {
274 config.Set<DelayAgnostic>(new DelayAgnostic(true));
bjornv@webrtc.org84f8ec12014-06-19 12:14:33 +0000275
peah6ebc4d32016-03-07 16:59:39 -0800276 } else if (strcmp(argv[i], "--aec3") == 0) {
277 config.Set<EchoCanceller3>(new EchoCanceller3(true));
peaha332e2d2016-02-17 01:11:16 -0800278
peah0332c2d2016-04-15 11:23:33 -0700279 } else if (strcmp(argv[i], "--refined_adaptive_filter") == 0) {
280 config.Set<RefinedAdaptiveFilter>(new RefinedAdaptiveFilter(true));
281
niklase@google.com470e71d2011-07-07 08:21:25 +0000282 } else if (strcmp(argv[i], "-aecm") == 0) {
283 ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(true));
284
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000285 } else if (strcmp(argv[i], "--aecm_echo_path_in_file") == 0) {
286 i++;
287 ASSERT_LT(i, argc) << "Specify filename after --aecm_echo_path_in_file";
288 aecm_echo_path_in_filename = argv[i];
289
290 } else if (strcmp(argv[i], "--aecm_echo_path_out_file") == 0) {
291 i++;
292 ASSERT_LT(i, argc) << "Specify filename after --aecm_echo_path_out_file";
293 aecm_echo_path_out_filename = argv[i];
294
andrew@webrtc.org1acb3b32013-04-26 00:39:27 +0000295 } else if (strcmp(argv[i], "--no_comfort_noise") == 0) {
296 ASSERT_EQ(apm->kNoError,
297 apm->echo_control_mobile()->enable_comfort_noise(false));
298
299 } else if (strcmp(argv[i], "--routing_mode") == 0) {
300 i++;
301 ASSERT_LT(i, argc) << "Specify mode after --routing_mode";
302 int routing_mode;
303 ASSERT_EQ(1, sscanf(argv[i], "%d", &routing_mode));
304 ASSERT_EQ(apm->kNoError,
305 apm->echo_control_mobile()->set_routing_mode(
306 static_cast<webrtc::EchoControlMobile::RoutingMode>(
307 routing_mode)));
308
niklase@google.com470e71d2011-07-07 08:21:25 +0000309 } else if (strcmp(argv[i], "-agc") == 0) {
310 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
311
312 } else if (strcmp(argv[i], "--analog") == 0) {
313 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
314 ASSERT_EQ(apm->kNoError,
315 apm->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
316
317 } else if (strcmp(argv[i], "--adaptive_digital") == 0) {
318 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
319 ASSERT_EQ(apm->kNoError,
320 apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
321
322 } else if (strcmp(argv[i], "--fixed_digital") == 0) {
323 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
324 ASSERT_EQ(apm->kNoError,
325 apm->gain_control()->set_mode(GainControl::kFixedDigital));
326
327 } else if (strcmp(argv[i], "--target_level") == 0) {
328 i++;
329 int level;
330 ASSERT_EQ(1, sscanf(argv[i], "%d", &level));
331
332 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
333 ASSERT_EQ(apm->kNoError,
334 apm->gain_control()->set_target_level_dbfs(level));
335
336 } else if (strcmp(argv[i], "--compression_gain") == 0) {
337 i++;
338 int gain;
339 ASSERT_EQ(1, sscanf(argv[i], "%d", &gain));
340
341 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
342 ASSERT_EQ(apm->kNoError,
343 apm->gain_control()->set_compression_gain_db(gain));
344
345 } else if (strcmp(argv[i], "--limiter") == 0) {
346 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
347 ASSERT_EQ(apm->kNoError,
348 apm->gain_control()->enable_limiter(true));
349
350 } else if (strcmp(argv[i], "--no_limiter") == 0) {
351 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
352 ASSERT_EQ(apm->kNoError,
353 apm->gain_control()->enable_limiter(false));
354
355 } else if (strcmp(argv[i], "-hpf") == 0) {
356 ASSERT_EQ(apm->kNoError, apm->high_pass_filter()->Enable(true));
357
358 } else if (strcmp(argv[i], "-ns") == 0) {
359 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
360
361 } else if (strcmp(argv[i], "--ns_low") == 0) {
362 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
363 ASSERT_EQ(apm->kNoError,
364 apm->noise_suppression()->set_level(NoiseSuppression::kLow));
365
366 } else if (strcmp(argv[i], "--ns_moderate") == 0) {
367 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
368 ASSERT_EQ(apm->kNoError,
369 apm->noise_suppression()->set_level(NoiseSuppression::kModerate));
370
371 } else if (strcmp(argv[i], "--ns_high") == 0) {
372 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
373 ASSERT_EQ(apm->kNoError,
374 apm->noise_suppression()->set_level(NoiseSuppression::kHigh));
375
376 } else if (strcmp(argv[i], "--ns_very_high") == 0) {
377 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
378 ASSERT_EQ(apm->kNoError,
379 apm->noise_suppression()->set_level(NoiseSuppression::kVeryHigh));
380
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000381 } else if (strcmp(argv[i], "--ns_prob_file") == 0) {
382 i++;
383 ASSERT_LT(i, argc) << "Specify filename after --ns_prob_file";
384 ns_prob_filename = argv[i];
385
niklase@google.com470e71d2011-07-07 08:21:25 +0000386 } else if (strcmp(argv[i], "-vad") == 0) {
387 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
388
andrew@webrtc.org89752612012-10-12 16:41:45 +0000389 } else if (strcmp(argv[i], "--vad_very_low") == 0) {
390 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
391 ASSERT_EQ(apm->kNoError,
392 apm->voice_detection()->set_likelihood(
393 VoiceDetection::kVeryLowLikelihood));
394
395 } else if (strcmp(argv[i], "--vad_low") == 0) {
396 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
397 ASSERT_EQ(apm->kNoError,
398 apm->voice_detection()->set_likelihood(
399 VoiceDetection::kLowLikelihood));
400
401 } else if (strcmp(argv[i], "--vad_moderate") == 0) {
402 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
403 ASSERT_EQ(apm->kNoError,
404 apm->voice_detection()->set_likelihood(
405 VoiceDetection::kModerateLikelihood));
406
407 } else if (strcmp(argv[i], "--vad_high") == 0) {
408 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
409 ASSERT_EQ(apm->kNoError,
410 apm->voice_detection()->set_likelihood(
411 VoiceDetection::kHighLikelihood));
412
niklase@google.com470e71d2011-07-07 08:21:25 +0000413 } else if (strcmp(argv[i], "--vad_out_file") == 0) {
414 i++;
415 ASSERT_LT(i, argc) << "Specify filename after --vad_out_file";
416 vad_out_filename = argv[i];
417
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +0000418 } else if (strcmp(argv[i], "-expns") == 0) {
aluebs@webrtc.org9825afc2014-06-30 17:39:53 +0000419 config.Set<ExperimentalNs>(new ExperimentalNs(true));
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +0000420
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000421 } else if (strcmp(argv[i], "--noasm") == 0) {
422 WebRtc_GetCPUInfo = WebRtc_GetCPUInfoNoASM;
423 // We need to reinitialize here if components have already been enabled.
424 ASSERT_EQ(apm->kNoError, apm->Initialize());
425
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000426 } else if (strcmp(argv[i], "--add_delay") == 0) {
andrew@webrtc.org4b13fc92011-11-09 19:27:11 +0000427 i++;
428 ASSERT_EQ(1, sscanf(argv[i], "%d", &extra_delay_ms));
429
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000430 } else if (strcmp(argv[i], "--delay") == 0) {
431 i++;
432 ASSERT_EQ(1, sscanf(argv[i], "%d", &override_delay_ms));
433
niklase@google.com470e71d2011-07-07 08:21:25 +0000434 } else if (strcmp(argv[i], "--perf") == 0) {
435 perf_testing = true;
436
437 } else if (strcmp(argv[i], "--quiet") == 0) {
438 verbose = false;
439 progress = false;
440
441 } else if (strcmp(argv[i], "--no_progress") == 0) {
442 progress = false;
443
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000444 } else if (strcmp(argv[i], "--raw_output") == 0) {
445 raw_output = true;
446
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000447 } else if (strcmp(argv[i], "--debug_file") == 0) {
ajm@google.com808e0e02011-08-03 21:08:51 +0000448 i++;
andrew@webrtc.orgcb181212011-10-26 00:27:17 +0000449 ASSERT_LT(i, argc) << "Specify filename after --debug_file";
ivocd66b44d2016-01-15 03:06:36 -0800450 ASSERT_EQ(apm->kNoError, apm->StartDebugRecording(argv[i], -1));
niklase@google.com470e71d2011-07-07 08:21:25 +0000451 } else {
452 FAIL() << "Unrecognized argument " << argv[i];
453 }
454 }
Bjorn Volckerbeb97982015-04-28 13:52:50 +0200455 apm->SetExtraOptions(config);
456
ajm@google.com808e0e02011-08-03 21:08:51 +0000457 // If we're reading a protobuf file, ensure a simulation hasn't also
458 // been requested (which makes no sense...)
459 ASSERT_FALSE(pb_filename && simulating);
niklase@google.com470e71d2011-07-07 08:21:25 +0000460
461 if (verbose) {
462 printf("Sample rate: %d Hz\n", sample_rate_hz);
Peter Kasting69558702016-01-12 16:26:35 -0800463 printf("Primary channels: %" PRIuS " (in), %" PRIuS " (out)\n",
niklase@google.com470e71d2011-07-07 08:21:25 +0000464 num_capture_input_channels,
465 num_capture_output_channels);
Peter Kasting69558702016-01-12 16:26:35 -0800466 printf("Reverse channels: %" PRIuS "\n", num_render_channels);
niklase@google.com470e71d2011-07-07 08:21:25 +0000467 }
468
kjellander@webrtc.org10abe252012-12-17 18:28:07 +0000469 const std::string out_path = webrtc::test::OutputPath();
niklase@google.com470e71d2011-07-07 08:21:25 +0000470 const char far_file_default[] = "apm_far.pcm";
471 const char near_file_default[] = "apm_near.pcm";
niklase@google.com470e71d2011-07-07 08:21:25 +0000472 const char event_filename[] = "apm_event.dat";
473 const char delay_filename[] = "apm_delay.dat";
474 const char drift_filename[] = "apm_drift.dat";
kjellander@webrtc.org10abe252012-12-17 18:28:07 +0000475 const std::string vad_file_default = out_path + "vad_out.dat";
476 const std::string ns_prob_file_default = out_path + "ns_prob.dat";
niklase@google.com470e71d2011-07-07 08:21:25 +0000477
478 if (!simulating) {
479 far_filename = far_file_default;
480 near_filename = near_file_default;
481 }
482
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000483 if (out_filename.size() == 0) {
484 out_filename = out_path + "out";
niklase@google.com470e71d2011-07-07 08:21:25 +0000485 }
486
ajm@google.com808e0e02011-08-03 21:08:51 +0000487 if (!vad_out_filename) {
kjellander@webrtc.org10abe252012-12-17 18:28:07 +0000488 vad_out_filename = vad_file_default.c_str();
niklase@google.com470e71d2011-07-07 08:21:25 +0000489 }
490
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000491 if (!ns_prob_filename) {
kjellander@webrtc.org10abe252012-12-17 18:28:07 +0000492 ns_prob_filename = ns_prob_file_default.c_str();
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000493 }
494
ajm@google.com808e0e02011-08-03 21:08:51 +0000495 FILE* pb_file = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000496 FILE* far_file = NULL;
497 FILE* near_file = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000498 FILE* event_file = NULL;
499 FILE* delay_file = NULL;
500 FILE* drift_file = NULL;
501 FILE* vad_out_file = NULL;
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000502 FILE* ns_prob_file = NULL;
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000503 FILE* aecm_echo_path_in_file = NULL;
504 FILE* aecm_echo_path_out_file = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000505
kwiberg62eaacf2016-02-17 06:39:05 -0800506 std::unique_ptr<WavWriter> output_wav_file;
507 std::unique_ptr<RawFile> output_raw_file;
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000508
ajm@google.com808e0e02011-08-03 21:08:51 +0000509 if (pb_filename) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000510 pb_file = OpenFile(pb_filename, "rb");
ajm@google.com808e0e02011-08-03 21:08:51 +0000511 } else {
512 if (far_filename) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000513 far_file = OpenFile(far_filename, "rb");
ajm@google.com808e0e02011-08-03 21:08:51 +0000514 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000515
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000516 near_file = OpenFile(near_filename, "rb");
ajm@google.com808e0e02011-08-03 21:08:51 +0000517 if (!simulating) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000518 event_file = OpenFile(event_filename, "rb");
519 delay_file = OpenFile(delay_filename, "rb");
520 drift_file = OpenFile(drift_filename, "rb");
ajm@google.com808e0e02011-08-03 21:08:51 +0000521 }
522 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000523
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000524 int near_size_bytes = 0;
ajm@google.com808e0e02011-08-03 21:08:51 +0000525 if (pb_file) {
526 struct stat st;
527 stat(pb_filename, &st);
528 // Crude estimate, but should be good enough.
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000529 near_size_bytes = st.st_size / 3;
ajm@google.com808e0e02011-08-03 21:08:51 +0000530 } else {
531 struct stat st;
532 stat(near_filename, &st);
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000533 near_size_bytes = st.st_size;
niklase@google.com470e71d2011-07-07 08:21:25 +0000534 }
535
536 if (apm->voice_detection()->is_enabled()) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000537 vad_out_file = OpenFile(vad_out_filename, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000538 }
539
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000540 if (apm->noise_suppression()->is_enabled()) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000541 ns_prob_file = OpenFile(ns_prob_filename, "wb");
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000542 }
543
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000544 if (aecm_echo_path_in_filename != NULL) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000545 aecm_echo_path_in_file = OpenFile(aecm_echo_path_in_filename, "rb");
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000546
ajm@google.com22e65152011-07-18 18:03:01 +0000547 const size_t path_size =
548 apm->echo_control_mobile()->echo_path_size_bytes();
kwiberg62eaacf2016-02-17 06:39:05 -0800549 std::unique_ptr<char[]> echo_path(new char[path_size]);
andrew@webrtc.org3119ecf2011-11-01 17:00:18 +0000550 ASSERT_EQ(path_size, fread(echo_path.get(),
551 sizeof(char),
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000552 path_size,
553 aecm_echo_path_in_file));
554 EXPECT_EQ(apm->kNoError,
andrew@webrtc.org3119ecf2011-11-01 17:00:18 +0000555 apm->echo_control_mobile()->SetEchoPath(echo_path.get(),
556 path_size));
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000557 fclose(aecm_echo_path_in_file);
558 aecm_echo_path_in_file = NULL;
559 }
560
561 if (aecm_echo_path_out_filename != NULL) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000562 aecm_echo_path_out_file = OpenFile(aecm_echo_path_out_filename, "wb");
bjornv@google.comc4b939c2011-07-13 08:09:56 +0000563 }
564
niklase@google.com470e71d2011-07-07 08:21:25 +0000565 size_t read_count = 0;
566 int reverse_count = 0;
567 int primary_count = 0;
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000568 int near_read_bytes = 0;
Niels Möllerd28db7f2016-05-10 16:31:47 +0200569 int64_t acc_nanos = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000570
571 AudioFrame far_frame;
niklase@google.com470e71d2011-07-07 08:21:25 +0000572 AudioFrame near_frame;
niklase@google.com470e71d2011-07-07 08:21:25 +0000573
574 int delay_ms = 0;
575 int drift_samples = 0;
576 int capture_level = 127;
577 int8_t stream_has_voice = 0;
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000578 float ns_speech_prob = 0.0f;
niklase@google.com470e71d2011-07-07 08:21:25 +0000579
Niels Möllerd28db7f2016-05-10 16:31:47 +0200580 int64_t t0 = rtc::TimeNanos();
581 int64_t t1 = t0;
pbos@webrtc.orgb7192b82013-04-10 07:50:54 +0000582 int64_t max_time_us = 0;
583 int64_t max_time_reverse_us = 0;
584 int64_t min_time_us = 1e6;
585 int64_t min_time_reverse_us = 1e6;
niklase@google.com470e71d2011-07-07 08:21:25 +0000586
ajm@google.com808e0e02011-08-03 21:08:51 +0000587 // TODO(ajm): Ideally we would refactor this block into separate functions,
588 // but for now we want to share the variables.
589 if (pb_file) {
590 Event event_msg;
kwiberg62eaacf2016-02-17 06:39:05 -0800591 std::unique_ptr<ChannelBuffer<float> > reverse_cb;
592 std::unique_ptr<ChannelBuffer<float> > primary_cb;
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000593 int output_sample_rate = 32000;
594 AudioProcessing::ChannelLayout output_layout = AudioProcessing::kMono;
ajm@google.com808e0e02011-08-03 21:08:51 +0000595 while (ReadMessageFromFile(pb_file, &event_msg)) {
596 std::ostringstream trace_stream;
597 trace_stream << "Processed frames: " << reverse_count << " (reverse), "
598 << primary_count << " (primary)";
599 SCOPED_TRACE(trace_stream.str());
niklase@google.com470e71d2011-07-07 08:21:25 +0000600
ajm@google.com808e0e02011-08-03 21:08:51 +0000601 if (event_msg.type() == Event::INIT) {
602 ASSERT_TRUE(event_msg.has_init());
603 const Init msg = event_msg.init();
niklase@google.com470e71d2011-07-07 08:21:25 +0000604
ajm@google.com808e0e02011-08-03 21:08:51 +0000605 ASSERT_TRUE(msg.has_sample_rate());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000606 ASSERT_TRUE(msg.has_num_input_channels());
607 ASSERT_TRUE(msg.has_num_output_channels());
608 ASSERT_TRUE(msg.has_num_reverse_channels());
609 int reverse_sample_rate = msg.sample_rate();
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000610 if (msg.has_reverse_sample_rate()) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000611 reverse_sample_rate = msg.reverse_sample_rate();
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000612 }
613 output_sample_rate = msg.sample_rate();
614 if (msg.has_output_sample_rate()) {
615 output_sample_rate = msg.output_sample_rate();
616 }
Peter Kasting69558702016-01-12 16:26:35 -0800617 output_layout =
618 LayoutFromChannels(static_cast<size_t>(msg.num_output_channels()));
619 ASSERT_EQ(kNoErr,
620 apm->Initialize(
621 msg.sample_rate(),
622 output_sample_rate,
623 reverse_sample_rate,
624 LayoutFromChannels(
625 static_cast<size_t>(msg.num_input_channels())),
626 output_layout,
627 LayoutFromChannels(
628 static_cast<size_t>(msg.num_reverse_channels()))));
ajm@google.com808e0e02011-08-03 21:08:51 +0000629
630 samples_per_channel = msg.sample_rate() / 100;
bjornv@webrtc.orgee300822014-11-13 11:00:10 +0000631 far_frame.sample_rate_hz_ = reverse_sample_rate;
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000632 far_frame.samples_per_channel_ = reverse_sample_rate / 100;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000633 far_frame.num_channels_ = msg.num_reverse_channels();
634 near_frame.sample_rate_hz_ = msg.sample_rate();
635 near_frame.samples_per_channel_ = samples_per_channel;
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000636 near_frame.num_channels_ = msg.num_input_channels();
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000637 reverse_cb.reset(new ChannelBuffer<float>(
638 far_frame.samples_per_channel_,
639 msg.num_reverse_channels()));
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000640 primary_cb.reset(new ChannelBuffer<float>(samples_per_channel,
641 msg.num_input_channels()));
ajm@google.com808e0e02011-08-03 21:08:51 +0000642
643 if (verbose) {
644 printf("Init at frame: %d (primary), %d (reverse)\n",
645 primary_count, reverse_count);
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000646 printf(" Primary rates: %d Hz (in), %d Hz (out)\n",
647 msg.sample_rate(), output_sample_rate);
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000648 printf(" Primary channels: %d (in), %d (out)\n",
649 msg.num_input_channels(),
650 msg.num_output_channels());
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000651 printf(" Reverse rate: %d\n", reverse_sample_rate);
652 printf(" Reverse channels: %d\n", msg.num_reverse_channels());
ajm@google.com808e0e02011-08-03 21:08:51 +0000653 }
654
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000655 if (!raw_output) {
aluebsb0ad43b2015-11-20 00:11:53 -0800656 // The WAV file needs to be reset every time, because it can't change
657 // its sample rate or number of channels.
Peter Kasting69558702016-01-12 16:26:35 -0800658 output_wav_file.reset(new WavWriter(
659 out_filename + ".wav", output_sample_rate,
660 static_cast<size_t>(msg.num_output_channels())));
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000661 }
662
ajm@google.com808e0e02011-08-03 21:08:51 +0000663 } else if (event_msg.type() == Event::REVERSE_STREAM) {
664 ASSERT_TRUE(event_msg.has_reverse_stream());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000665 ReverseStream msg = event_msg.reverse_stream();
ajm@google.com808e0e02011-08-03 21:08:51 +0000666 reverse_count++;
667
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000668 ASSERT_TRUE(msg.has_data() ^ (msg.channel_size() > 0));
669 if (msg.has_data()) {
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000670 ASSERT_EQ(sizeof(int16_t) * far_frame.samples_per_channel_ *
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000671 far_frame.num_channels_, msg.data().size());
672 memcpy(far_frame.data_, msg.data().data(), msg.data().size());
673 } else {
674 for (int i = 0; i < msg.channel_size(); ++i) {
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +0000675 memcpy(reverse_cb->channels()[i],
676 msg.channel(i).data(),
677 reverse_cb->num_frames() *
678 sizeof(reverse_cb->channels()[i][0]));
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000679 }
680 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000681
682 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200683 t0 = rtc::TimeNanos();
ajm@google.com808e0e02011-08-03 21:08:51 +0000684 }
685
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000686 if (msg.has_data()) {
687 ASSERT_EQ(apm->kNoError,
aluebsb0319552016-03-17 20:39:53 -0700688 apm->ProcessReverseStream(&far_frame));
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000689 } else {
690 ASSERT_EQ(apm->kNoError,
691 apm->AnalyzeReverseStream(
692 reverse_cb->channels(),
693 far_frame.samples_per_channel_,
694 far_frame.sample_rate_hz_,
695 LayoutFromChannels(far_frame.num_channels_)));
696 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000697
698 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200699 t1 = rtc::TimeNanos();
700 int64_t diff_nanos = t1 - t0;
701 acc_nanos += diff_nanos;
702 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec;
703 if (diff_us > max_time_reverse_us) {
704 max_time_reverse_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000705 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200706 if (diff_us < min_time_reverse_us) {
707 min_time_reverse_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000708 }
709 }
710
711 } else if (event_msg.type() == Event::STREAM) {
712 ASSERT_TRUE(event_msg.has_stream());
713 const Stream msg = event_msg.stream();
714 primary_count++;
715
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000716 ASSERT_TRUE(msg.has_input_data() ^ (msg.input_channel_size() > 0));
717 if (msg.has_input_data()) {
718 ASSERT_EQ(sizeof(int16_t) * samples_per_channel *
719 near_frame.num_channels_, msg.input_data().size());
720 memcpy(near_frame.data_,
721 msg.input_data().data(),
722 msg.input_data().size());
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000723 near_read_bytes += msg.input_data().size();
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000724 } else {
725 for (int i = 0; i < msg.input_channel_size(); ++i) {
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +0000726 memcpy(primary_cb->channels()[i],
727 msg.input_channel(i).data(),
728 primary_cb->num_frames() *
729 sizeof(primary_cb->channels()[i][0]));
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000730 near_read_bytes += msg.input_channel(i).size();
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000731 }
732 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000733
ajm@google.com808e0e02011-08-03 21:08:51 +0000734 if (progress && primary_count % 100 == 0) {
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000735 near_read_bytes = std::min(near_read_bytes, near_size_bytes);
ajm@google.com808e0e02011-08-03 21:08:51 +0000736 printf("%.0f%% complete\r",
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000737 (near_read_bytes * 100.0) / near_size_bytes);
ajm@google.com808e0e02011-08-03 21:08:51 +0000738 fflush(stdout);
739 }
740
741 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200742 t0 = rtc::TimeNanos();
ajm@google.com808e0e02011-08-03 21:08:51 +0000743 }
744
745 ASSERT_EQ(apm->kNoError,
746 apm->gain_control()->set_stream_analog_level(msg.level()));
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000747 delay_ms = msg.delay() + extra_delay_ms;
748 if (override_delay_ms) {
749 delay_ms = override_delay_ms;
750 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000751 ASSERT_EQ(apm->kNoError,
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000752 apm->set_stream_delay_ms(delay_ms));
andrew@webrtc.org6be1e932013-03-01 18:47:28 +0000753 apm->echo_cancellation()->set_stream_drift_samples(msg.drift());
ajm@google.com808e0e02011-08-03 21:08:51 +0000754
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +0000755 if (msg.has_keypress()) {
756 apm->set_stream_key_pressed(msg.keypress());
757 } else {
758 apm->set_stream_key_pressed(true);
759 }
760
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000761 int err = apm->kNoError;
762 if (msg.has_input_data()) {
763 err = apm->ProcessStream(&near_frame);
764 ASSERT_TRUE(near_frame.num_channels_ == apm->num_output_channels());
765 } else {
766 err = apm->ProcessStream(
767 primary_cb->channels(),
768 near_frame.samples_per_channel_,
769 near_frame.sample_rate_hz_,
770 LayoutFromChannels(near_frame.num_channels_),
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000771 output_sample_rate,
772 output_layout,
773 primary_cb->channels());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000774 }
775
ajm@google.com808e0e02011-08-03 21:08:51 +0000776 if (err == apm->kBadStreamParameterWarning) {
777 printf("Bad parameter warning. %s\n", trace_stream.str().c_str());
778 }
779 ASSERT_TRUE(err == apm->kNoError ||
780 err == apm->kBadStreamParameterWarning);
781
ajm@google.com808e0e02011-08-03 21:08:51 +0000782 stream_has_voice =
783 static_cast<int8_t>(apm->voice_detection()->stream_has_voice());
784 if (vad_out_file != NULL) {
785 ASSERT_EQ(1u, fwrite(&stream_has_voice,
786 sizeof(stream_has_voice),
787 1,
788 vad_out_file));
789 }
790
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000791 if (ns_prob_file != NULL) {
792 ns_speech_prob = apm->noise_suppression()->speech_probability();
793 ASSERT_EQ(1u, fwrite(&ns_speech_prob,
794 sizeof(ns_speech_prob),
795 1,
796 ns_prob_file));
797 }
798
ajm@google.com808e0e02011-08-03 21:08:51 +0000799 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200800 t1 = rtc::TimeNanos();
801 int64_t diff_nanos = t1 - t0;
802 acc_nanos += diff_nanos;
803 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec;
804 if (diff_us > max_time_us) {
805 max_time_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000806 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200807 if (diff_us < min_time_us) {
808 min_time_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000809 }
810 }
811
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000812 const size_t samples_per_channel = output_sample_rate / 100;
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000813 if (msg.has_input_data()) {
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000814 if (raw_output && !output_raw_file) {
815 output_raw_file.reset(new RawFile(out_filename + ".pcm"));
816 }
817 WriteIntData(near_frame.data_,
818 apm->num_output_channels() * samples_per_channel,
819 output_wav_file.get(),
820 output_raw_file.get());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000821 } else {
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000822 if (raw_output && !output_raw_file) {
823 output_raw_file.reset(new RawFile(out_filename + ".float"));
824 }
825 WriteFloatData(primary_cb->channels(),
826 samples_per_channel,
827 apm->num_output_channels(),
828 output_wav_file.get(),
829 output_raw_file.get());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000830 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000831 }
832 }
833
834 ASSERT_TRUE(feof(pb_file));
ajm@google.com808e0e02011-08-03 21:08:51 +0000835
836 } else {
bjornv@google.coma2c6ea02011-09-27 08:04:45 +0000837 enum Events {
838 kInitializeEvent,
839 kRenderEvent,
840 kCaptureEvent,
841 kResetEventDeprecated
842 };
843 int16_t event = 0;
ajm@google.com808e0e02011-08-03 21:08:51 +0000844 while (simulating || feof(event_file) == 0) {
845 std::ostringstream trace_stream;
846 trace_stream << "Processed frames: " << reverse_count << " (reverse), "
847 << primary_count << " (primary)";
848 SCOPED_TRACE(trace_stream.str());
849
850 if (simulating) {
851 if (far_file == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000852 event = kCaptureEvent;
853 } else {
peah58cf5f12016-02-16 07:26:21 -0800854 event = (event == kCaptureEvent) ? kRenderEvent : kCaptureEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000855 }
856 } else {
ajm@google.com808e0e02011-08-03 21:08:51 +0000857 read_count = fread(&event, sizeof(event), 1, event_file);
858 if (read_count != 1) {
859 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000860 }
861 }
862
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000863 far_frame.sample_rate_hz_ = sample_rate_hz;
864 far_frame.samples_per_channel_ = samples_per_channel;
865 far_frame.num_channels_ = num_render_channels;
866 near_frame.sample_rate_hz_ = sample_rate_hz;
867 near_frame.samples_per_channel_ = samples_per_channel;
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000868
ajm@google.com808e0e02011-08-03 21:08:51 +0000869 if (event == kInitializeEvent || event == kResetEventDeprecated) {
870 ASSERT_EQ(1u,
871 fread(&sample_rate_hz, sizeof(sample_rate_hz), 1, event_file));
872 samples_per_channel = sample_rate_hz / 100;
niklase@google.com470e71d2011-07-07 08:21:25 +0000873
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000874 int32_t unused_device_sample_rate_hz;
ajm@google.com808e0e02011-08-03 21:08:51 +0000875 ASSERT_EQ(1u,
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000876 fread(&unused_device_sample_rate_hz,
877 sizeof(unused_device_sample_rate_hz),
ajm@google.com808e0e02011-08-03 21:08:51 +0000878 1,
879 event_file));
880
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000881 ASSERT_EQ(kNoErr, apm->Initialize(
882 sample_rate_hz,
883 sample_rate_hz,
884 sample_rate_hz,
885 LayoutFromChannels(num_capture_input_channels),
886 LayoutFromChannels(num_capture_output_channels),
887 LayoutFromChannels(num_render_channels)));
ajm@google.com808e0e02011-08-03 21:08:51 +0000888
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000889 far_frame.sample_rate_hz_ = sample_rate_hz;
890 far_frame.samples_per_channel_ = samples_per_channel;
891 far_frame.num_channels_ = num_render_channels;
892 near_frame.sample_rate_hz_ = sample_rate_hz;
893 near_frame.samples_per_channel_ = samples_per_channel;
ajm@google.com808e0e02011-08-03 21:08:51 +0000894
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000895 if (!raw_output) {
bjornv@webrtc.org634c9262014-09-24 12:21:51 +0000896 // The WAV file needs to be reset every time, because it can't change
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000897 // it's sample rate or number of channels.
andrew@webrtc.orga3ed7132014-10-31 21:51:03 +0000898 output_wav_file.reset(new WavWriter(out_filename + ".wav",
899 sample_rate_hz,
900 num_capture_output_channels));
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000901 }
902
ajm@google.com808e0e02011-08-03 21:08:51 +0000903 if (verbose) {
904 printf("Init at frame: %d (primary), %d (reverse)\n",
905 primary_count, reverse_count);
906 printf(" Sample rate: %d Hz\n", sample_rate_hz);
907 }
908
909 } else if (event == kRenderEvent) {
910 reverse_count++;
ajm@google.com808e0e02011-08-03 21:08:51 +0000911
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000912 size_t size = samples_per_channel * num_render_channels;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000913 read_count = fread(far_frame.data_,
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000914 sizeof(int16_t),
915 size,
ajm@google.com808e0e02011-08-03 21:08:51 +0000916 far_file);
917
918 if (simulating) {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000919 if (read_count != size) {
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000920 // Read an equal amount from the near file to avoid errors due to
921 // not reaching end-of-file.
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000922 EXPECT_EQ(0, fseek(near_file, read_count * sizeof(int16_t),
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000923 SEEK_CUR));
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700924 break; // This is expected.
ajm@google.com808e0e02011-08-03 21:08:51 +0000925 }
926 } else {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000927 ASSERT_EQ(size, read_count);
ajm@google.com808e0e02011-08-03 21:08:51 +0000928 }
929
930 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200931 t0 = rtc::TimeNanos();
ajm@google.com808e0e02011-08-03 21:08:51 +0000932 }
933
934 ASSERT_EQ(apm->kNoError,
aluebsb0319552016-03-17 20:39:53 -0700935 apm->ProcessReverseStream(&far_frame));
ajm@google.com808e0e02011-08-03 21:08:51 +0000936
937 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200938 t1 = rtc::TimeNanos();
939 int64_t diff_nanos = t1 - t0;
940 acc_nanos += diff_nanos;
941 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec;
942 if (diff_us > max_time_reverse_us) {
943 max_time_reverse_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000944 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200945 if (diff_us < min_time_reverse_us) {
946 min_time_reverse_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000947 }
948 }
949
950 } else if (event == kCaptureEvent) {
951 primary_count++;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000952 near_frame.num_channels_ = num_capture_input_channels;
ajm@google.com808e0e02011-08-03 21:08:51 +0000953
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000954 size_t size = samples_per_channel * num_capture_input_channels;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000955 read_count = fread(near_frame.data_,
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000956 sizeof(int16_t),
957 size,
ajm@google.com808e0e02011-08-03 21:08:51 +0000958 near_file);
959
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000960 near_read_bytes += read_count * sizeof(int16_t);
ajm@google.com808e0e02011-08-03 21:08:51 +0000961 if (progress && primary_count % 100 == 0) {
962 printf("%.0f%% complete\r",
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000963 (near_read_bytes * 100.0) / near_size_bytes);
ajm@google.com808e0e02011-08-03 21:08:51 +0000964 fflush(stdout);
965 }
966 if (simulating) {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000967 if (read_count != size) {
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700968 break; // This is expected.
ajm@google.com808e0e02011-08-03 21:08:51 +0000969 }
970
971 delay_ms = 0;
972 drift_samples = 0;
973 } else {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000974 ASSERT_EQ(size, read_count);
ajm@google.com808e0e02011-08-03 21:08:51 +0000975
976 // TODO(ajm): sizeof(delay_ms) for current files?
977 ASSERT_EQ(1u,
978 fread(&delay_ms, 2, 1, delay_file));
979 ASSERT_EQ(1u,
980 fread(&drift_samples, sizeof(drift_samples), 1, drift_file));
981 }
982
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000983 if (apm->gain_control()->is_enabled() &&
984 apm->gain_control()->mode() == GainControl::kAdaptiveAnalog) {
andrew@webrtc.org81865342012-10-27 00:28:27 +0000985 SimulateMic(capture_level, &near_frame);
986 }
987
ajm@google.com808e0e02011-08-03 21:08:51 +0000988 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200989 t0 = rtc::TimeNanos();
ajm@google.com808e0e02011-08-03 21:08:51 +0000990 }
991
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000992 const int capture_level_in = capture_level;
ajm@google.com808e0e02011-08-03 21:08:51 +0000993 ASSERT_EQ(apm->kNoError,
994 apm->gain_control()->set_stream_analog_level(capture_level));
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000995 delay_ms += extra_delay_ms;
996 if (override_delay_ms) {
997 delay_ms = override_delay_ms;
998 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000999 ASSERT_EQ(apm->kNoError,
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +00001000 apm->set_stream_delay_ms(delay_ms));
andrew@webrtc.org6be1e932013-03-01 18:47:28 +00001001 apm->echo_cancellation()->set_stream_drift_samples(drift_samples);
ajm@google.com808e0e02011-08-03 21:08:51 +00001002
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +00001003 apm->set_stream_key_pressed(true);
1004
ajm@google.com808e0e02011-08-03 21:08:51 +00001005 int err = apm->ProcessStream(&near_frame);
1006 if (err == apm->kBadStreamParameterWarning) {
1007 printf("Bad parameter warning. %s\n", trace_stream.str().c_str());
1008 }
1009 ASSERT_TRUE(err == apm->kNoError ||
1010 err == apm->kBadStreamParameterWarning);
andrew@webrtc.org63a50982012-05-02 23:56:37 +00001011 ASSERT_TRUE(near_frame.num_channels_ == apm->num_output_channels());
ajm@google.com808e0e02011-08-03 21:08:51 +00001012
1013 capture_level = apm->gain_control()->stream_analog_level();
1014
1015 stream_has_voice =
1016 static_cast<int8_t>(apm->voice_detection()->stream_has_voice());
1017 if (vad_out_file != NULL) {
1018 ASSERT_EQ(1u, fwrite(&stream_has_voice,
1019 sizeof(stream_has_voice),
1020 1,
1021 vad_out_file));
1022 }
1023
bjornv@webrtc.org08329f42012-07-12 21:00:43 +00001024 if (ns_prob_file != NULL) {
1025 ns_speech_prob = apm->noise_suppression()->speech_probability();
1026 ASSERT_EQ(1u, fwrite(&ns_speech_prob,
1027 sizeof(ns_speech_prob),
1028 1,
1029 ns_prob_file));
1030 }
1031
ajm@google.com808e0e02011-08-03 21:08:51 +00001032 if (apm->gain_control()->mode() != GainControl::kAdaptiveAnalog) {
1033 ASSERT_EQ(capture_level_in, capture_level);
1034 }
1035
1036 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +02001037 t1 = rtc::TimeNanos();
1038 int64_t diff_nanos = t1 - t0;
1039 acc_nanos += diff_nanos;
1040 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec;
1041 if (diff_us > max_time_us) {
1042 max_time_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +00001043 }
Niels Möllerd28db7f2016-05-10 16:31:47 +02001044 if (diff_us < min_time_us) {
1045 min_time_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +00001046 }
1047 }
1048
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +00001049 if (raw_output && !output_raw_file) {
1050 output_raw_file.reset(new RawFile(out_filename + ".pcm"));
1051 }
bjornv@webrtc.org634c9262014-09-24 12:21:51 +00001052 if (!raw_output && !output_wav_file) {
andrew@webrtc.orga3ed7132014-10-31 21:51:03 +00001053 output_wav_file.reset(new WavWriter(out_filename + ".wav",
1054 sample_rate_hz,
1055 num_capture_output_channels));
bjornv@webrtc.org634c9262014-09-24 12:21:51 +00001056 }
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +00001057 WriteIntData(near_frame.data_,
1058 size,
1059 output_wav_file.get(),
1060 output_raw_file.get());
Andrew MacDonaldcb05b722015-05-07 22:17:51 -07001061 } else {
ajm@google.com808e0e02011-08-03 21:08:51 +00001062 FAIL() << "Event " << event << " is unrecognized";
niklase@google.com470e71d2011-07-07 08:21:25 +00001063 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001064 }
1065 }
peahc1cd2bb2015-11-09 10:38:07 -08001066 if (progress) {
1067 printf("100%% complete\r");
1068 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001069
bjornv@google.comc4b939c2011-07-13 08:09:56 +00001070 if (aecm_echo_path_out_file != NULL) {
ajm@google.com22e65152011-07-18 18:03:01 +00001071 const size_t path_size =
1072 apm->echo_control_mobile()->echo_path_size_bytes();
kwiberg62eaacf2016-02-17 06:39:05 -08001073 std::unique_ptr<char[]> echo_path(new char[path_size]);
andrew@webrtc.org3119ecf2011-11-01 17:00:18 +00001074 apm->echo_control_mobile()->GetEchoPath(echo_path.get(), path_size);
1075 ASSERT_EQ(path_size, fwrite(echo_path.get(),
1076 sizeof(char),
bjornv@google.comc4b939c2011-07-13 08:09:56 +00001077 path_size,
1078 aecm_echo_path_out_file));
1079 fclose(aecm_echo_path_out_file);
1080 aecm_echo_path_out_file = NULL;
1081 }
1082
niklase@google.com470e71d2011-07-07 08:21:25 +00001083 if (verbose) {
1084 printf("\nProcessed frames: %d (primary), %d (reverse)\n",
1085 primary_count, reverse_count);
andrew@webrtc.org94c74132011-09-19 15:17:57 +00001086
andrew@webrtc.org755b04a2011-11-15 16:57:56 +00001087 if (apm->level_estimator()->is_enabled()) {
1088 printf("\n--Level metrics--\n");
1089 printf("RMS: %d dBFS\n", -apm->level_estimator()->RMS());
1090 }
andrew@webrtc.org94c74132011-09-19 15:17:57 +00001091 if (apm->echo_cancellation()->are_metrics_enabled()) {
1092 EchoCancellation::Metrics metrics;
1093 apm->echo_cancellation()->GetMetrics(&metrics);
1094 printf("\n--Echo metrics--\n");
1095 printf("(avg, max, min)\n");
1096 printf("ERL: ");
1097 PrintStat(metrics.echo_return_loss);
1098 printf("ERLE: ");
1099 PrintStat(metrics.echo_return_loss_enhancement);
1100 printf("ANLP: ");
1101 PrintStat(metrics.a_nlp);
1102 }
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +00001103 if (apm->echo_cancellation()->is_delay_logging_enabled()) {
1104 int median = 0;
1105 int std = 0;
bjornv@webrtc.orgb1786db2015-02-03 06:06:26 +00001106 float fraction_poor_delays = 0;
1107 apm->echo_cancellation()->GetDelayMetrics(&median, &std,
1108 &fraction_poor_delays);
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +00001109 printf("\n--Delay metrics--\n");
1110 printf("Median: %3d\n", median);
1111 printf("Standard deviation: %3d\n", std);
bjornv@webrtc.orgb1786db2015-02-03 06:06:26 +00001112 printf("Poor delay values: %3.1f%%\n", fraction_poor_delays * 100);
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +00001113 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001114 }
1115
ajm@google.com808e0e02011-08-03 21:08:51 +00001116 if (!pb_file) {
1117 int8_t temp_int8;
1118 if (far_file) {
1119 read_count = fread(&temp_int8, sizeof(temp_int8), 1, far_file);
1120 EXPECT_NE(0, feof(far_file)) << "Far-end file not fully processed";
1121 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001122
ajm@google.com808e0e02011-08-03 21:08:51 +00001123 read_count = fread(&temp_int8, sizeof(temp_int8), 1, near_file);
1124 EXPECT_NE(0, feof(near_file)) << "Near-end file not fully processed";
1125
1126 if (!simulating) {
1127 read_count = fread(&temp_int8, sizeof(temp_int8), 1, event_file);
1128 EXPECT_NE(0, feof(event_file)) << "Event file not fully processed";
1129 read_count = fread(&temp_int8, sizeof(temp_int8), 1, delay_file);
1130 EXPECT_NE(0, feof(delay_file)) << "Delay file not fully processed";
1131 read_count = fread(&temp_int8, sizeof(temp_int8), 1, drift_file);
1132 EXPECT_NE(0, feof(drift_file)) << "Drift file not fully processed";
1133 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001134 }
1135
1136 if (perf_testing) {
1137 if (primary_count > 0) {
Niels Möllerd28db7f2016-05-10 16:31:47 +02001138 int64_t exec_time = acc_nanos / rtc::kNumNanosecsPerMillisec;
niklase@google.com470e71d2011-07-07 08:21:25 +00001139 printf("\nTotal time: %.3f s, file time: %.2f s\n",
1140 exec_time * 0.001, primary_count * 0.01);
1141 printf("Time per frame: %.3f ms (average), %.3f ms (max),"
1142 " %.3f ms (min)\n",
1143 (exec_time * 1.0) / primary_count,
1144 (max_time_us + max_time_reverse_us) / 1000.0,
1145 (min_time_us + min_time_reverse_us) / 1000.0);
kma@webrtc.org0e739502012-12-07 15:26:28 +00001146 // Record the results with Perf test tools.
kjellander@webrtc.org00ab7cf2013-02-11 12:33:03 +00001147 webrtc::test::PrintResult("audioproc", "", "time_per_10ms_frame",
kma@webrtc.org0e739502012-12-07 15:26:28 +00001148 (exec_time * 1000) / primary_count, "us", false);
niklase@google.com470e71d2011-07-07 08:21:25 +00001149 } else {
1150 printf("Warning: no capture frames\n");
1151 }
1152 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001153}
andrew@webrtc.orga8b97372014-03-10 22:26:12 +00001154
ajm@google.com808e0e02011-08-03 21:08:51 +00001155} // namespace
andrew@webrtc.orga8b97372014-03-10 22:26:12 +00001156} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +00001157
Andrew MacDonaldcb05b722015-05-07 22:17:51 -07001158int main(int argc, char* argv[]) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +00001159 webrtc::void_main(argc, argv);
niklase@google.com470e71d2011-07-07 08:21:25 +00001160
andrew@webrtc.org64235092011-08-19 21:22:08 +00001161 // Optional, but removes memory leak noise from Valgrind.
1162 google::protobuf::ShutdownProtobufLibrary();
niklase@google.com470e71d2011-07-07 08:21:25 +00001163 return 0;
1164}