blob: 527e0a1e3e58cd5666375f67607577321e952395 [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");
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;
Niels Möllerd28db7f2016-05-10 16:31:47 +0200565 int64_t acc_nanos = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000566
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
Niels Möllerd28db7f2016-05-10 16:31:47 +0200576 int64_t t0 = rtc::TimeNanos();
577 int64_t 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) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200679 t0 = rtc::TimeNanos();
ajm@google.com808e0e02011-08-03 21:08:51 +0000680 }
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) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200695 t1 = rtc::TimeNanos();
696 int64_t diff_nanos = t1 - t0;
697 acc_nanos += diff_nanos;
698 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec;
699 if (diff_us > max_time_reverse_us) {
700 max_time_reverse_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000701 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200702 if (diff_us < min_time_reverse_us) {
703 min_time_reverse_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000704 }
705 }
706
707 } else if (event_msg.type() == Event::STREAM) {
708 ASSERT_TRUE(event_msg.has_stream());
709 const Stream msg = event_msg.stream();
710 primary_count++;
711
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000712 // ProcessStream could have changed this for the output frame.
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000713 near_frame.num_channels_ = apm->num_input_channels();
ajm@google.com808e0e02011-08-03 21:08:51 +0000714
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000715 ASSERT_TRUE(msg.has_input_data() ^ (msg.input_channel_size() > 0));
716 if (msg.has_input_data()) {
717 ASSERT_EQ(sizeof(int16_t) * samples_per_channel *
718 near_frame.num_channels_, msg.input_data().size());
719 memcpy(near_frame.data_,
720 msg.input_data().data(),
721 msg.input_data().size());
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000722 near_read_bytes += msg.input_data().size();
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000723 } else {
724 for (int i = 0; i < msg.input_channel_size(); ++i) {
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +0000725 memcpy(primary_cb->channels()[i],
726 msg.input_channel(i).data(),
727 primary_cb->num_frames() *
728 sizeof(primary_cb->channels()[i][0]));
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000729 near_read_bytes += msg.input_channel(i).size();
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000730 }
731 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000732
ajm@google.com808e0e02011-08-03 21:08:51 +0000733 if (progress && primary_count % 100 == 0) {
aluebs@webrtc.org74cf9162014-09-03 11:05:01 +0000734 near_read_bytes = std::min(near_read_bytes, near_size_bytes);
ajm@google.com808e0e02011-08-03 21:08:51 +0000735 printf("%.0f%% complete\r",
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000736 (near_read_bytes * 100.0) / near_size_bytes);
ajm@google.com808e0e02011-08-03 21:08:51 +0000737 fflush(stdout);
738 }
739
740 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200741 t0 = rtc::TimeNanos();
ajm@google.com808e0e02011-08-03 21:08:51 +0000742 }
743
744 ASSERT_EQ(apm->kNoError,
745 apm->gain_control()->set_stream_analog_level(msg.level()));
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000746 delay_ms = msg.delay() + extra_delay_ms;
747 if (override_delay_ms) {
748 delay_ms = override_delay_ms;
749 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000750 ASSERT_EQ(apm->kNoError,
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000751 apm->set_stream_delay_ms(delay_ms));
andrew@webrtc.org6be1e932013-03-01 18:47:28 +0000752 apm->echo_cancellation()->set_stream_drift_samples(msg.drift());
ajm@google.com808e0e02011-08-03 21:08:51 +0000753
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +0000754 if (msg.has_keypress()) {
755 apm->set_stream_key_pressed(msg.keypress());
756 } else {
757 apm->set_stream_key_pressed(true);
758 }
759
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000760 int err = apm->kNoError;
761 if (msg.has_input_data()) {
762 err = apm->ProcessStream(&near_frame);
763 ASSERT_TRUE(near_frame.num_channels_ == apm->num_output_channels());
764 } else {
765 err = apm->ProcessStream(
766 primary_cb->channels(),
767 near_frame.samples_per_channel_,
768 near_frame.sample_rate_hz_,
769 LayoutFromChannels(near_frame.num_channels_),
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000770 output_sample_rate,
771 output_layout,
772 primary_cb->channels());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000773 }
774
ajm@google.com808e0e02011-08-03 21:08:51 +0000775 if (err == apm->kBadStreamParameterWarning) {
776 printf("Bad parameter warning. %s\n", trace_stream.str().c_str());
777 }
778 ASSERT_TRUE(err == apm->kNoError ||
779 err == apm->kBadStreamParameterWarning);
780
ajm@google.com808e0e02011-08-03 21:08:51 +0000781 stream_has_voice =
782 static_cast<int8_t>(apm->voice_detection()->stream_has_voice());
783 if (vad_out_file != NULL) {
784 ASSERT_EQ(1u, fwrite(&stream_has_voice,
785 sizeof(stream_has_voice),
786 1,
787 vad_out_file));
788 }
789
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000790 if (ns_prob_file != NULL) {
791 ns_speech_prob = apm->noise_suppression()->speech_probability();
792 ASSERT_EQ(1u, fwrite(&ns_speech_prob,
793 sizeof(ns_speech_prob),
794 1,
795 ns_prob_file));
796 }
797
ajm@google.com808e0e02011-08-03 21:08:51 +0000798 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200799 t1 = rtc::TimeNanos();
800 int64_t diff_nanos = t1 - t0;
801 acc_nanos += diff_nanos;
802 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec;
803 if (diff_us > max_time_us) {
804 max_time_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000805 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200806 if (diff_us < min_time_us) {
807 min_time_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000808 }
809 }
810
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000811 const size_t samples_per_channel = output_sample_rate / 100;
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000812 if (msg.has_input_data()) {
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000813 if (raw_output && !output_raw_file) {
814 output_raw_file.reset(new RawFile(out_filename + ".pcm"));
815 }
816 WriteIntData(near_frame.data_,
817 apm->num_output_channels() * samples_per_channel,
818 output_wav_file.get(),
819 output_raw_file.get());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000820 } else {
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000821 if (raw_output && !output_raw_file) {
822 output_raw_file.reset(new RawFile(out_filename + ".float"));
823 }
824 WriteFloatData(primary_cb->channels(),
825 samples_per_channel,
826 apm->num_output_channels(),
827 output_wav_file.get(),
828 output_raw_file.get());
andrew@webrtc.orga8b97372014-03-10 22:26:12 +0000829 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000830 }
831 }
832
833 ASSERT_TRUE(feof(pb_file));
ajm@google.com808e0e02011-08-03 21:08:51 +0000834
835 } else {
bjornv@google.coma2c6ea02011-09-27 08:04:45 +0000836 enum Events {
837 kInitializeEvent,
838 kRenderEvent,
839 kCaptureEvent,
840 kResetEventDeprecated
841 };
842 int16_t event = 0;
ajm@google.com808e0e02011-08-03 21:08:51 +0000843 while (simulating || feof(event_file) == 0) {
844 std::ostringstream trace_stream;
845 trace_stream << "Processed frames: " << reverse_count << " (reverse), "
846 << primary_count << " (primary)";
847 SCOPED_TRACE(trace_stream.str());
848
849 if (simulating) {
850 if (far_file == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000851 event = kCaptureEvent;
852 } else {
peah58cf5f12016-02-16 07:26:21 -0800853 event = (event == kCaptureEvent) ? kRenderEvent : kCaptureEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000854 }
855 } else {
ajm@google.com808e0e02011-08-03 21:08:51 +0000856 read_count = fread(&event, sizeof(event), 1, event_file);
857 if (read_count != 1) {
858 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000859 }
860 }
861
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000862 far_frame.sample_rate_hz_ = sample_rate_hz;
863 far_frame.samples_per_channel_ = samples_per_channel;
864 far_frame.num_channels_ = num_render_channels;
865 near_frame.sample_rate_hz_ = sample_rate_hz;
866 near_frame.samples_per_channel_ = samples_per_channel;
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000867
ajm@google.com808e0e02011-08-03 21:08:51 +0000868 if (event == kInitializeEvent || event == kResetEventDeprecated) {
869 ASSERT_EQ(1u,
870 fread(&sample_rate_hz, sizeof(sample_rate_hz), 1, event_file));
871 samples_per_channel = sample_rate_hz / 100;
niklase@google.com470e71d2011-07-07 08:21:25 +0000872
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000873 int32_t unused_device_sample_rate_hz;
ajm@google.com808e0e02011-08-03 21:08:51 +0000874 ASSERT_EQ(1u,
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000875 fread(&unused_device_sample_rate_hz,
876 sizeof(unused_device_sample_rate_hz),
ajm@google.com808e0e02011-08-03 21:08:51 +0000877 1,
878 event_file));
879
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000880 ASSERT_EQ(kNoErr, apm->Initialize(
881 sample_rate_hz,
882 sample_rate_hz,
883 sample_rate_hz,
884 LayoutFromChannels(num_capture_input_channels),
885 LayoutFromChannels(num_capture_output_channels),
886 LayoutFromChannels(num_render_channels)));
ajm@google.com808e0e02011-08-03 21:08:51 +0000887
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000888 far_frame.sample_rate_hz_ = sample_rate_hz;
889 far_frame.samples_per_channel_ = samples_per_channel;
890 far_frame.num_channels_ = num_render_channels;
891 near_frame.sample_rate_hz_ = sample_rate_hz;
892 near_frame.samples_per_channel_ = samples_per_channel;
ajm@google.com808e0e02011-08-03 21:08:51 +0000893
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000894 if (!raw_output) {
bjornv@webrtc.org634c9262014-09-24 12:21:51 +0000895 // The WAV file needs to be reset every time, because it can't change
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000896 // it's sample rate or number of channels.
andrew@webrtc.orga3ed7132014-10-31 21:51:03 +0000897 output_wav_file.reset(new WavWriter(out_filename + ".wav",
898 sample_rate_hz,
899 num_capture_output_channels));
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +0000900 }
901
ajm@google.com808e0e02011-08-03 21:08:51 +0000902 if (verbose) {
903 printf("Init at frame: %d (primary), %d (reverse)\n",
904 primary_count, reverse_count);
905 printf(" Sample rate: %d Hz\n", sample_rate_hz);
906 }
907
908 } else if (event == kRenderEvent) {
909 reverse_count++;
ajm@google.com808e0e02011-08-03 21:08:51 +0000910
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000911 size_t size = samples_per_channel * num_render_channels;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000912 read_count = fread(far_frame.data_,
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000913 sizeof(int16_t),
914 size,
ajm@google.com808e0e02011-08-03 21:08:51 +0000915 far_file);
916
917 if (simulating) {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000918 if (read_count != size) {
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000919 // Read an equal amount from the near file to avoid errors due to
920 // not reaching end-of-file.
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000921 EXPECT_EQ(0, fseek(near_file, read_count * sizeof(int16_t),
andrew@webrtc.org94c74132011-09-19 15:17:57 +0000922 SEEK_CUR));
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700923 break; // This is expected.
ajm@google.com808e0e02011-08-03 21:08:51 +0000924 }
925 } else {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000926 ASSERT_EQ(size, read_count);
ajm@google.com808e0e02011-08-03 21:08:51 +0000927 }
928
929 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200930 t0 = rtc::TimeNanos();
ajm@google.com808e0e02011-08-03 21:08:51 +0000931 }
932
933 ASSERT_EQ(apm->kNoError,
aluebsb0319552016-03-17 20:39:53 -0700934 apm->ProcessReverseStream(&far_frame));
ajm@google.com808e0e02011-08-03 21:08:51 +0000935
936 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200937 t1 = rtc::TimeNanos();
938 int64_t diff_nanos = t1 - t0;
939 acc_nanos += diff_nanos;
940 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec;
941 if (diff_us > max_time_reverse_us) {
942 max_time_reverse_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000943 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200944 if (diff_us < min_time_reverse_us) {
945 min_time_reverse_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +0000946 }
947 }
948
949 } else if (event == kCaptureEvent) {
950 primary_count++;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000951 near_frame.num_channels_ = num_capture_input_channels;
ajm@google.com808e0e02011-08-03 21:08:51 +0000952
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000953 size_t size = samples_per_channel * num_capture_input_channels;
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000954 read_count = fread(near_frame.data_,
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000955 sizeof(int16_t),
956 size,
ajm@google.com808e0e02011-08-03 21:08:51 +0000957 near_file);
958
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000959 near_read_bytes += read_count * sizeof(int16_t);
ajm@google.com808e0e02011-08-03 21:08:51 +0000960 if (progress && primary_count % 100 == 0) {
961 printf("%.0f%% complete\r",
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000962 (near_read_bytes * 100.0) / near_size_bytes);
ajm@google.com808e0e02011-08-03 21:08:51 +0000963 fflush(stdout);
964 }
965 if (simulating) {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000966 if (read_count != size) {
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700967 break; // This is expected.
ajm@google.com808e0e02011-08-03 21:08:51 +0000968 }
969
970 delay_ms = 0;
971 drift_samples = 0;
972 } else {
andrew@webrtc.org755b04a2011-11-15 16:57:56 +0000973 ASSERT_EQ(size, read_count);
ajm@google.com808e0e02011-08-03 21:08:51 +0000974
975 // TODO(ajm): sizeof(delay_ms) for current files?
976 ASSERT_EQ(1u,
977 fread(&delay_ms, 2, 1, delay_file));
978 ASSERT_EQ(1u,
979 fread(&drift_samples, sizeof(drift_samples), 1, drift_file));
980 }
981
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000982 if (apm->gain_control()->is_enabled() &&
983 apm->gain_control()->mode() == GainControl::kAdaptiveAnalog) {
andrew@webrtc.org81865342012-10-27 00:28:27 +0000984 SimulateMic(capture_level, &near_frame);
985 }
986
ajm@google.com808e0e02011-08-03 21:08:51 +0000987 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200988 t0 = rtc::TimeNanos();
ajm@google.com808e0e02011-08-03 21:08:51 +0000989 }
990
andrew@webrtc.orgbafdae32013-01-11 23:11:29 +0000991 const int capture_level_in = capture_level;
ajm@google.com808e0e02011-08-03 21:08:51 +0000992 ASSERT_EQ(apm->kNoError,
993 apm->gain_control()->set_stream_analog_level(capture_level));
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000994 delay_ms += extra_delay_ms;
995 if (override_delay_ms) {
996 delay_ms = override_delay_ms;
997 }
ajm@google.com808e0e02011-08-03 21:08:51 +0000998 ASSERT_EQ(apm->kNoError,
andrew@webrtc.orgca764ab2013-10-07 16:44:32 +0000999 apm->set_stream_delay_ms(delay_ms));
andrew@webrtc.org6be1e932013-03-01 18:47:28 +00001000 apm->echo_cancellation()->set_stream_drift_samples(drift_samples);
ajm@google.com808e0e02011-08-03 21:08:51 +00001001
aluebs@webrtc.orgbc1d2242014-02-25 16:50:22 +00001002 apm->set_stream_key_pressed(true);
1003
ajm@google.com808e0e02011-08-03 21:08:51 +00001004 int err = apm->ProcessStream(&near_frame);
1005 if (err == apm->kBadStreamParameterWarning) {
1006 printf("Bad parameter warning. %s\n", trace_stream.str().c_str());
1007 }
1008 ASSERT_TRUE(err == apm->kNoError ||
1009 err == apm->kBadStreamParameterWarning);
andrew@webrtc.org63a50982012-05-02 23:56:37 +00001010 ASSERT_TRUE(near_frame.num_channels_ == apm->num_output_channels());
ajm@google.com808e0e02011-08-03 21:08:51 +00001011
1012 capture_level = apm->gain_control()->stream_analog_level();
1013
1014 stream_has_voice =
1015 static_cast<int8_t>(apm->voice_detection()->stream_has_voice());
1016 if (vad_out_file != NULL) {
1017 ASSERT_EQ(1u, fwrite(&stream_has_voice,
1018 sizeof(stream_has_voice),
1019 1,
1020 vad_out_file));
1021 }
1022
bjornv@webrtc.org08329f42012-07-12 21:00:43 +00001023 if (ns_prob_file != NULL) {
1024 ns_speech_prob = apm->noise_suppression()->speech_probability();
1025 ASSERT_EQ(1u, fwrite(&ns_speech_prob,
1026 sizeof(ns_speech_prob),
1027 1,
1028 ns_prob_file));
1029 }
1030
ajm@google.com808e0e02011-08-03 21:08:51 +00001031 if (apm->gain_control()->mode() != GainControl::kAdaptiveAnalog) {
1032 ASSERT_EQ(capture_level_in, capture_level);
1033 }
1034
1035 if (perf_testing) {
Niels Möllerd28db7f2016-05-10 16:31:47 +02001036 t1 = rtc::TimeNanos();
1037 int64_t diff_nanos = t1 - t0;
1038 acc_nanos += diff_nanos;
1039 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec;
1040 if (diff_us > max_time_us) {
1041 max_time_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +00001042 }
Niels Möllerd28db7f2016-05-10 16:31:47 +02001043 if (diff_us < min_time_us) {
1044 min_time_us = diff_us;
ajm@google.com808e0e02011-08-03 21:08:51 +00001045 }
1046 }
1047
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +00001048 if (raw_output && !output_raw_file) {
1049 output_raw_file.reset(new RawFile(out_filename + ".pcm"));
1050 }
bjornv@webrtc.org634c9262014-09-24 12:21:51 +00001051 if (!raw_output && !output_wav_file) {
andrew@webrtc.orga3ed7132014-10-31 21:51:03 +00001052 output_wav_file.reset(new WavWriter(out_filename + ".wav",
1053 sample_rate_hz,
1054 num_capture_output_channels));
bjornv@webrtc.org634c9262014-09-24 12:21:51 +00001055 }
aluebs@webrtc.org021e76f2014-09-04 18:12:00 +00001056 WriteIntData(near_frame.data_,
1057 size,
1058 output_wav_file.get(),
1059 output_raw_file.get());
Andrew MacDonaldcb05b722015-05-07 22:17:51 -07001060 } else {
ajm@google.com808e0e02011-08-03 21:08:51 +00001061 FAIL() << "Event " << event << " is unrecognized";
niklase@google.com470e71d2011-07-07 08:21:25 +00001062 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001063 }
1064 }
peahc1cd2bb2015-11-09 10:38:07 -08001065 if (progress) {
1066 printf("100%% complete\r");
1067 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001068
bjornv@google.comc4b939c2011-07-13 08:09:56 +00001069 if (aecm_echo_path_out_file != NULL) {
ajm@google.com22e65152011-07-18 18:03:01 +00001070 const size_t path_size =
1071 apm->echo_control_mobile()->echo_path_size_bytes();
kwiberg62eaacf2016-02-17 06:39:05 -08001072 std::unique_ptr<char[]> echo_path(new char[path_size]);
andrew@webrtc.org3119ecf2011-11-01 17:00:18 +00001073 apm->echo_control_mobile()->GetEchoPath(echo_path.get(), path_size);
1074 ASSERT_EQ(path_size, fwrite(echo_path.get(),
1075 sizeof(char),
bjornv@google.comc4b939c2011-07-13 08:09:56 +00001076 path_size,
1077 aecm_echo_path_out_file));
1078 fclose(aecm_echo_path_out_file);
1079 aecm_echo_path_out_file = NULL;
1080 }
1081
niklase@google.com470e71d2011-07-07 08:21:25 +00001082 if (verbose) {
1083 printf("\nProcessed frames: %d (primary), %d (reverse)\n",
1084 primary_count, reverse_count);
andrew@webrtc.org94c74132011-09-19 15:17:57 +00001085
andrew@webrtc.org755b04a2011-11-15 16:57:56 +00001086 if (apm->level_estimator()->is_enabled()) {
1087 printf("\n--Level metrics--\n");
1088 printf("RMS: %d dBFS\n", -apm->level_estimator()->RMS());
1089 }
andrew@webrtc.org94c74132011-09-19 15:17:57 +00001090 if (apm->echo_cancellation()->are_metrics_enabled()) {
1091 EchoCancellation::Metrics metrics;
1092 apm->echo_cancellation()->GetMetrics(&metrics);
1093 printf("\n--Echo metrics--\n");
1094 printf("(avg, max, min)\n");
1095 printf("ERL: ");
1096 PrintStat(metrics.echo_return_loss);
1097 printf("ERLE: ");
1098 PrintStat(metrics.echo_return_loss_enhancement);
1099 printf("ANLP: ");
1100 PrintStat(metrics.a_nlp);
1101 }
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +00001102 if (apm->echo_cancellation()->is_delay_logging_enabled()) {
1103 int median = 0;
1104 int std = 0;
bjornv@webrtc.orgb1786db2015-02-03 06:06:26 +00001105 float fraction_poor_delays = 0;
1106 apm->echo_cancellation()->GetDelayMetrics(&median, &std,
1107 &fraction_poor_delays);
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +00001108 printf("\n--Delay metrics--\n");
1109 printf("Median: %3d\n", median);
1110 printf("Standard deviation: %3d\n", std);
bjornv@webrtc.orgb1786db2015-02-03 06:06:26 +00001111 printf("Poor delay values: %3.1f%%\n", fraction_poor_delays * 100);
bjornv@google.com1ba3dbe2011-10-03 08:18:10 +00001112 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001113 }
1114
ajm@google.com808e0e02011-08-03 21:08:51 +00001115 if (!pb_file) {
1116 int8_t temp_int8;
1117 if (far_file) {
1118 read_count = fread(&temp_int8, sizeof(temp_int8), 1, far_file);
1119 EXPECT_NE(0, feof(far_file)) << "Far-end file not fully processed";
1120 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001121
ajm@google.com808e0e02011-08-03 21:08:51 +00001122 read_count = fread(&temp_int8, sizeof(temp_int8), 1, near_file);
1123 EXPECT_NE(0, feof(near_file)) << "Near-end file not fully processed";
1124
1125 if (!simulating) {
1126 read_count = fread(&temp_int8, sizeof(temp_int8), 1, event_file);
1127 EXPECT_NE(0, feof(event_file)) << "Event file not fully processed";
1128 read_count = fread(&temp_int8, sizeof(temp_int8), 1, delay_file);
1129 EXPECT_NE(0, feof(delay_file)) << "Delay file not fully processed";
1130 read_count = fread(&temp_int8, sizeof(temp_int8), 1, drift_file);
1131 EXPECT_NE(0, feof(drift_file)) << "Drift file not fully processed";
1132 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001133 }
1134
1135 if (perf_testing) {
1136 if (primary_count > 0) {
Niels Möllerd28db7f2016-05-10 16:31:47 +02001137 int64_t exec_time = acc_nanos / rtc::kNumNanosecsPerMillisec;
niklase@google.com470e71d2011-07-07 08:21:25 +00001138 printf("\nTotal time: %.3f s, file time: %.2f s\n",
1139 exec_time * 0.001, primary_count * 0.01);
1140 printf("Time per frame: %.3f ms (average), %.3f ms (max),"
1141 " %.3f ms (min)\n",
1142 (exec_time * 1.0) / primary_count,
1143 (max_time_us + max_time_reverse_us) / 1000.0,
1144 (min_time_us + min_time_reverse_us) / 1000.0);
kma@webrtc.org0e739502012-12-07 15:26:28 +00001145 // Record the results with Perf test tools.
kjellander@webrtc.org00ab7cf2013-02-11 12:33:03 +00001146 webrtc::test::PrintResult("audioproc", "", "time_per_10ms_frame",
kma@webrtc.org0e739502012-12-07 15:26:28 +00001147 (exec_time * 1000) / primary_count, "us", false);
niklase@google.com470e71d2011-07-07 08:21:25 +00001148 } else {
1149 printf("Warning: no capture frames\n");
1150 }
1151 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001152}
andrew@webrtc.orga8b97372014-03-10 22:26:12 +00001153
ajm@google.com808e0e02011-08-03 21:08:51 +00001154} // namespace
andrew@webrtc.orga8b97372014-03-10 22:26:12 +00001155} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +00001156
Andrew MacDonaldcb05b722015-05-07 22:17:51 -07001157int main(int argc, char* argv[]) {
andrew@webrtc.orga8b97372014-03-10 22:26:12 +00001158 webrtc::void_main(argc, argv);
niklase@google.com470e71d2011-07-07 08:21:25 +00001159
andrew@webrtc.org64235092011-08-19 21:22:08 +00001160 // Optional, but removes memory leak noise from Valgrind.
1161 google::protobuf::ShutdownProtobufLibrary();
niklase@google.com470e71d2011-07-07 08:21:25 +00001162 return 0;
1163}