1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker // Commandline tool to unpack audioproc debug files.
12*d9f75844SAndroid Build Coastguard Worker //
13*d9f75844SAndroid Build Coastguard Worker // The debug files are dumped as protobuf blobs. For analysis, it's necessary
14*d9f75844SAndroid Build Coastguard Worker // to unpack the file into its component parts: audio and other data.
15*d9f75844SAndroid Build Coastguard Worker
16*d9f75844SAndroid Build Coastguard Worker #include <inttypes.h>
17*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
18*d9f75844SAndroid Build Coastguard Worker #include <stdio.h>
19*d9f75844SAndroid Build Coastguard Worker #include <stdlib.h>
20*d9f75844SAndroid Build Coastguard Worker
21*d9f75844SAndroid Build Coastguard Worker #include <memory>
22*d9f75844SAndroid Build Coastguard Worker #include <string>
23*d9f75844SAndroid Build Coastguard Worker #include <vector>
24*d9f75844SAndroid Build Coastguard Worker
25*d9f75844SAndroid Build Coastguard Worker #include "absl/flags/flag.h"
26*d9f75844SAndroid Build Coastguard Worker #include "absl/flags/parse.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/function_view.h"
28*d9f75844SAndroid Build Coastguard Worker #include "common_audio/include/audio_util.h"
29*d9f75844SAndroid Build Coastguard Worker #include "common_audio/wav_file.h"
30*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/test/protobuf_utils.h"
31*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
32*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ignore_wundef.h"
33*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
34*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/arch.h"
35*d9f75844SAndroid Build Coastguard Worker
36*d9f75844SAndroid Build Coastguard Worker RTC_PUSH_IGNORING_WUNDEF()
37*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/debug.pb.h"
38*d9f75844SAndroid Build Coastguard Worker RTC_POP_IGNORING_WUNDEF()
39*d9f75844SAndroid Build Coastguard Worker
40*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(std::string,
41*d9f75844SAndroid Build Coastguard Worker input_file,
42*d9f75844SAndroid Build Coastguard Worker "input",
43*d9f75844SAndroid Build Coastguard Worker "The name of the input stream file.");
44*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(std::string,
45*d9f75844SAndroid Build Coastguard Worker output_file,
46*d9f75844SAndroid Build Coastguard Worker "ref_out",
47*d9f75844SAndroid Build Coastguard Worker "The name of the reference output stream file.");
48*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(std::string,
49*d9f75844SAndroid Build Coastguard Worker reverse_file,
50*d9f75844SAndroid Build Coastguard Worker "reverse",
51*d9f75844SAndroid Build Coastguard Worker "The name of the reverse input stream file.");
52*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(std::string,
53*d9f75844SAndroid Build Coastguard Worker delay_file,
54*d9f75844SAndroid Build Coastguard Worker "delay.int32",
55*d9f75844SAndroid Build Coastguard Worker "The name of the delay file.");
56*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(std::string,
57*d9f75844SAndroid Build Coastguard Worker drift_file,
58*d9f75844SAndroid Build Coastguard Worker "drift.int32",
59*d9f75844SAndroid Build Coastguard Worker "The name of the drift file.");
60*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(std::string,
61*d9f75844SAndroid Build Coastguard Worker level_file,
62*d9f75844SAndroid Build Coastguard Worker "level.int32",
63*d9f75844SAndroid Build Coastguard Worker "The name of the applied input volume file.");
64*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(std::string,
65*d9f75844SAndroid Build Coastguard Worker keypress_file,
66*d9f75844SAndroid Build Coastguard Worker "keypress.bool",
67*d9f75844SAndroid Build Coastguard Worker "The name of the keypress file.");
68*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(std::string,
69*d9f75844SAndroid Build Coastguard Worker callorder_file,
70*d9f75844SAndroid Build Coastguard Worker "callorder",
71*d9f75844SAndroid Build Coastguard Worker "The name of the render/capture call order file.");
72*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(std::string,
73*d9f75844SAndroid Build Coastguard Worker settings_file,
74*d9f75844SAndroid Build Coastguard Worker "settings.txt",
75*d9f75844SAndroid Build Coastguard Worker "The name of the settings file.");
76*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(bool,
77*d9f75844SAndroid Build Coastguard Worker full,
78*d9f75844SAndroid Build Coastguard Worker false,
79*d9f75844SAndroid Build Coastguard Worker "Unpack the full set of files (normally not needed).");
80*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(bool, raw, false, "Write raw data instead of a WAV file.");
81*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(bool,
82*d9f75844SAndroid Build Coastguard Worker text,
83*d9f75844SAndroid Build Coastguard Worker false,
84*d9f75844SAndroid Build Coastguard Worker "Write non-audio files as text files instead of binary files.");
85*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(bool,
86*d9f75844SAndroid Build Coastguard Worker use_init_suffix,
87*d9f75844SAndroid Build Coastguard Worker false,
88*d9f75844SAndroid Build Coastguard Worker "Use init index instead of capture frame count as file name suffix.");
89*d9f75844SAndroid Build Coastguard Worker
90*d9f75844SAndroid Build Coastguard Worker #define PRINT_CONFIG(field_name) \
91*d9f75844SAndroid Build Coastguard Worker if (msg.has_##field_name()) { \
92*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " " #field_name ": %d\n", msg.field_name()); \
93*d9f75844SAndroid Build Coastguard Worker }
94*d9f75844SAndroid Build Coastguard Worker
95*d9f75844SAndroid Build Coastguard Worker #define PRINT_CONFIG_FLOAT(field_name) \
96*d9f75844SAndroid Build Coastguard Worker if (msg.has_##field_name()) { \
97*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " " #field_name ": %f\n", msg.field_name()); \
98*d9f75844SAndroid Build Coastguard Worker }
99*d9f75844SAndroid Build Coastguard Worker
100*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
101*d9f75844SAndroid Build Coastguard Worker
102*d9f75844SAndroid Build Coastguard Worker using audioproc::Event;
103*d9f75844SAndroid Build Coastguard Worker using audioproc::Init;
104*d9f75844SAndroid Build Coastguard Worker using audioproc::ReverseStream;
105*d9f75844SAndroid Build Coastguard Worker using audioproc::Stream;
106*d9f75844SAndroid Build Coastguard Worker
107*d9f75844SAndroid Build Coastguard Worker namespace {
108*d9f75844SAndroid Build Coastguard Worker class RawFile final {
109*d9f75844SAndroid Build Coastguard Worker public:
RawFile(const std::string & filename)110*d9f75844SAndroid Build Coastguard Worker explicit RawFile(const std::string& filename)
111*d9f75844SAndroid Build Coastguard Worker : file_handle_(fopen(filename.c_str(), "wb")) {}
~RawFile()112*d9f75844SAndroid Build Coastguard Worker ~RawFile() { fclose(file_handle_); }
113*d9f75844SAndroid Build Coastguard Worker
114*d9f75844SAndroid Build Coastguard Worker RawFile(const RawFile&) = delete;
115*d9f75844SAndroid Build Coastguard Worker RawFile& operator=(const RawFile&) = delete;
116*d9f75844SAndroid Build Coastguard Worker
WriteSamples(const int16_t * samples,size_t num_samples)117*d9f75844SAndroid Build Coastguard Worker void WriteSamples(const int16_t* samples, size_t num_samples) {
118*d9f75844SAndroid Build Coastguard Worker #ifndef WEBRTC_ARCH_LITTLE_ENDIAN
119*d9f75844SAndroid Build Coastguard Worker #error "Need to convert samples to little-endian when writing to PCM file"
120*d9f75844SAndroid Build Coastguard Worker #endif
121*d9f75844SAndroid Build Coastguard Worker fwrite(samples, sizeof(*samples), num_samples, file_handle_);
122*d9f75844SAndroid Build Coastguard Worker }
123*d9f75844SAndroid Build Coastguard Worker
WriteSamples(const float * samples,size_t num_samples)124*d9f75844SAndroid Build Coastguard Worker void WriteSamples(const float* samples, size_t num_samples) {
125*d9f75844SAndroid Build Coastguard Worker fwrite(samples, sizeof(*samples), num_samples, file_handle_);
126*d9f75844SAndroid Build Coastguard Worker }
127*d9f75844SAndroid Build Coastguard Worker
128*d9f75844SAndroid Build Coastguard Worker private:
129*d9f75844SAndroid Build Coastguard Worker FILE* file_handle_;
130*d9f75844SAndroid Build Coastguard Worker };
131*d9f75844SAndroid Build Coastguard Worker
WriteIntData(const int16_t * data,size_t length,WavWriter * wav_file,RawFile * raw_file)132*d9f75844SAndroid Build Coastguard Worker void WriteIntData(const int16_t* data,
133*d9f75844SAndroid Build Coastguard Worker size_t length,
134*d9f75844SAndroid Build Coastguard Worker WavWriter* wav_file,
135*d9f75844SAndroid Build Coastguard Worker RawFile* raw_file) {
136*d9f75844SAndroid Build Coastguard Worker if (wav_file) {
137*d9f75844SAndroid Build Coastguard Worker wav_file->WriteSamples(data, length);
138*d9f75844SAndroid Build Coastguard Worker }
139*d9f75844SAndroid Build Coastguard Worker if (raw_file) {
140*d9f75844SAndroid Build Coastguard Worker raw_file->WriteSamples(data, length);
141*d9f75844SAndroid Build Coastguard Worker }
142*d9f75844SAndroid Build Coastguard Worker }
143*d9f75844SAndroid Build Coastguard Worker
WriteFloatData(const float * const * data,size_t samples_per_channel,size_t num_channels,WavWriter * wav_file,RawFile * raw_file)144*d9f75844SAndroid Build Coastguard Worker void WriteFloatData(const float* const* data,
145*d9f75844SAndroid Build Coastguard Worker size_t samples_per_channel,
146*d9f75844SAndroid Build Coastguard Worker size_t num_channels,
147*d9f75844SAndroid Build Coastguard Worker WavWriter* wav_file,
148*d9f75844SAndroid Build Coastguard Worker RawFile* raw_file) {
149*d9f75844SAndroid Build Coastguard Worker size_t length = num_channels * samples_per_channel;
150*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<float[]> buffer(new float[length]);
151*d9f75844SAndroid Build Coastguard Worker Interleave(data, samples_per_channel, num_channels, buffer.get());
152*d9f75844SAndroid Build Coastguard Worker if (raw_file) {
153*d9f75844SAndroid Build Coastguard Worker raw_file->WriteSamples(buffer.get(), length);
154*d9f75844SAndroid Build Coastguard Worker }
155*d9f75844SAndroid Build Coastguard Worker // TODO(aluebs): Use ScaleToInt16Range() from audio_util
156*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < length; ++i) {
157*d9f75844SAndroid Build Coastguard Worker buffer[i] = buffer[i] > 0
158*d9f75844SAndroid Build Coastguard Worker ? buffer[i] * std::numeric_limits<int16_t>::max()
159*d9f75844SAndroid Build Coastguard Worker : -buffer[i] * std::numeric_limits<int16_t>::min();
160*d9f75844SAndroid Build Coastguard Worker }
161*d9f75844SAndroid Build Coastguard Worker if (wav_file) {
162*d9f75844SAndroid Build Coastguard Worker wav_file->WriteSamples(buffer.get(), length);
163*d9f75844SAndroid Build Coastguard Worker }
164*d9f75844SAndroid Build Coastguard Worker }
165*d9f75844SAndroid Build Coastguard Worker
166*d9f75844SAndroid Build Coastguard Worker // Exits on failure; do not use in unit tests.
OpenFile(const std::string & filename,const char * mode)167*d9f75844SAndroid Build Coastguard Worker FILE* OpenFile(const std::string& filename, const char* mode) {
168*d9f75844SAndroid Build Coastguard Worker FILE* file = fopen(filename.c_str(), mode);
169*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(file) << "Unable to open file " << filename;
170*d9f75844SAndroid Build Coastguard Worker return file;
171*d9f75844SAndroid Build Coastguard Worker }
172*d9f75844SAndroid Build Coastguard Worker
WriteData(const void * data,size_t size,FILE * file,const std::string & filename)173*d9f75844SAndroid Build Coastguard Worker void WriteData(const void* data,
174*d9f75844SAndroid Build Coastguard Worker size_t size,
175*d9f75844SAndroid Build Coastguard Worker FILE* file,
176*d9f75844SAndroid Build Coastguard Worker const std::string& filename) {
177*d9f75844SAndroid Build Coastguard Worker RTC_CHECK_EQ(fwrite(data, size, 1, file), 1)
178*d9f75844SAndroid Build Coastguard Worker << "Error when writing to " << filename.c_str();
179*d9f75844SAndroid Build Coastguard Worker }
180*d9f75844SAndroid Build Coastguard Worker
WriteCallOrderData(const bool render_call,FILE * file,const std::string & filename)181*d9f75844SAndroid Build Coastguard Worker void WriteCallOrderData(const bool render_call,
182*d9f75844SAndroid Build Coastguard Worker FILE* file,
183*d9f75844SAndroid Build Coastguard Worker const std::string& filename) {
184*d9f75844SAndroid Build Coastguard Worker const char call_type = render_call ? 'r' : 'c';
185*d9f75844SAndroid Build Coastguard Worker WriteData(&call_type, sizeof(call_type), file, filename.c_str());
186*d9f75844SAndroid Build Coastguard Worker }
187*d9f75844SAndroid Build Coastguard Worker
WritingCallOrderFile()188*d9f75844SAndroid Build Coastguard Worker bool WritingCallOrderFile() {
189*d9f75844SAndroid Build Coastguard Worker return absl::GetFlag(FLAGS_full);
190*d9f75844SAndroid Build Coastguard Worker }
191*d9f75844SAndroid Build Coastguard Worker
WritingRuntimeSettingFiles()192*d9f75844SAndroid Build Coastguard Worker bool WritingRuntimeSettingFiles() {
193*d9f75844SAndroid Build Coastguard Worker return absl::GetFlag(FLAGS_full);
194*d9f75844SAndroid Build Coastguard Worker }
195*d9f75844SAndroid Build Coastguard Worker
196*d9f75844SAndroid Build Coastguard Worker // Exports RuntimeSetting AEC dump events to Audacity-readable files.
197*d9f75844SAndroid Build Coastguard Worker // This class is not RAII compliant.
198*d9f75844SAndroid Build Coastguard Worker class RuntimeSettingWriter {
199*d9f75844SAndroid Build Coastguard Worker public:
RuntimeSettingWriter(std::string name,rtc::FunctionView<bool (const Event)> is_exporter_for,rtc::FunctionView<std::string (const Event)> get_timeline_label)200*d9f75844SAndroid Build Coastguard Worker RuntimeSettingWriter(
201*d9f75844SAndroid Build Coastguard Worker std::string name,
202*d9f75844SAndroid Build Coastguard Worker rtc::FunctionView<bool(const Event)> is_exporter_for,
203*d9f75844SAndroid Build Coastguard Worker rtc::FunctionView<std::string(const Event)> get_timeline_label)
204*d9f75844SAndroid Build Coastguard Worker : setting_name_(std::move(name)),
205*d9f75844SAndroid Build Coastguard Worker is_exporter_for_(is_exporter_for),
206*d9f75844SAndroid Build Coastguard Worker get_timeline_label_(get_timeline_label) {}
~RuntimeSettingWriter()207*d9f75844SAndroid Build Coastguard Worker ~RuntimeSettingWriter() { Flush(); }
208*d9f75844SAndroid Build Coastguard Worker
IsExporterFor(const Event & event) const209*d9f75844SAndroid Build Coastguard Worker bool IsExporterFor(const Event& event) const {
210*d9f75844SAndroid Build Coastguard Worker return is_exporter_for_(event);
211*d9f75844SAndroid Build Coastguard Worker }
212*d9f75844SAndroid Build Coastguard Worker
213*d9f75844SAndroid Build Coastguard Worker // Writes to file the payload of `event` using `frame_count` to calculate
214*d9f75844SAndroid Build Coastguard Worker // timestamp.
WriteEvent(const Event & event,int frame_count)215*d9f75844SAndroid Build Coastguard Worker void WriteEvent(const Event& event, int frame_count) {
216*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(is_exporter_for_(event));
217*d9f75844SAndroid Build Coastguard Worker if (file_ == nullptr) {
218*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder file_name;
219*d9f75844SAndroid Build Coastguard Worker file_name << setting_name_ << frame_offset_ << ".txt";
220*d9f75844SAndroid Build Coastguard Worker file_ = OpenFile(file_name.str(), "wb");
221*d9f75844SAndroid Build Coastguard Worker }
222*d9f75844SAndroid Build Coastguard Worker
223*d9f75844SAndroid Build Coastguard Worker // Time in the current WAV file, in seconds.
224*d9f75844SAndroid Build Coastguard Worker double time = (frame_count - frame_offset_) / 100.0;
225*d9f75844SAndroid Build Coastguard Worker std::string label = get_timeline_label_(event);
226*d9f75844SAndroid Build Coastguard Worker // In Audacity, all annotations are encoded as intervals.
227*d9f75844SAndroid Build Coastguard Worker fprintf(file_, "%.6f\t%.6f\t%s \n", time, time, label.c_str());
228*d9f75844SAndroid Build Coastguard Worker }
229*d9f75844SAndroid Build Coastguard Worker
230*d9f75844SAndroid Build Coastguard Worker // Handles an AEC dump initialization event, occurring at frame
231*d9f75844SAndroid Build Coastguard Worker // `frame_offset`.
HandleInitEvent(int frame_offset)232*d9f75844SAndroid Build Coastguard Worker void HandleInitEvent(int frame_offset) {
233*d9f75844SAndroid Build Coastguard Worker Flush();
234*d9f75844SAndroid Build Coastguard Worker frame_offset_ = frame_offset;
235*d9f75844SAndroid Build Coastguard Worker }
236*d9f75844SAndroid Build Coastguard Worker
237*d9f75844SAndroid Build Coastguard Worker private:
Flush()238*d9f75844SAndroid Build Coastguard Worker void Flush() {
239*d9f75844SAndroid Build Coastguard Worker if (file_ != nullptr) {
240*d9f75844SAndroid Build Coastguard Worker fclose(file_);
241*d9f75844SAndroid Build Coastguard Worker file_ = nullptr;
242*d9f75844SAndroid Build Coastguard Worker }
243*d9f75844SAndroid Build Coastguard Worker }
244*d9f75844SAndroid Build Coastguard Worker
245*d9f75844SAndroid Build Coastguard Worker FILE* file_ = nullptr;
246*d9f75844SAndroid Build Coastguard Worker int frame_offset_ = 0;
247*d9f75844SAndroid Build Coastguard Worker const std::string setting_name_;
248*d9f75844SAndroid Build Coastguard Worker const rtc::FunctionView<bool(Event)> is_exporter_for_;
249*d9f75844SAndroid Build Coastguard Worker const rtc::FunctionView<std::string(Event)> get_timeline_label_;
250*d9f75844SAndroid Build Coastguard Worker };
251*d9f75844SAndroid Build Coastguard Worker
252*d9f75844SAndroid Build Coastguard Worker // Returns RuntimeSetting exporters for runtime setting types defined in
253*d9f75844SAndroid Build Coastguard Worker // debug.proto.
RuntimeSettingWriters()254*d9f75844SAndroid Build Coastguard Worker std::vector<RuntimeSettingWriter> RuntimeSettingWriters() {
255*d9f75844SAndroid Build Coastguard Worker return {
256*d9f75844SAndroid Build Coastguard Worker RuntimeSettingWriter(
257*d9f75844SAndroid Build Coastguard Worker "CapturePreGain",
258*d9f75844SAndroid Build Coastguard Worker [](const Event& event) -> bool {
259*d9f75844SAndroid Build Coastguard Worker return event.runtime_setting().has_capture_pre_gain();
260*d9f75844SAndroid Build Coastguard Worker },
261*d9f75844SAndroid Build Coastguard Worker [](const Event& event) -> std::string {
262*d9f75844SAndroid Build Coastguard Worker return std::to_string(event.runtime_setting().capture_pre_gain());
263*d9f75844SAndroid Build Coastguard Worker }),
264*d9f75844SAndroid Build Coastguard Worker RuntimeSettingWriter(
265*d9f75844SAndroid Build Coastguard Worker "CustomRenderProcessingRuntimeSetting",
266*d9f75844SAndroid Build Coastguard Worker [](const Event& event) -> bool {
267*d9f75844SAndroid Build Coastguard Worker return event.runtime_setting()
268*d9f75844SAndroid Build Coastguard Worker .has_custom_render_processing_setting();
269*d9f75844SAndroid Build Coastguard Worker },
270*d9f75844SAndroid Build Coastguard Worker [](const Event& event) -> std::string {
271*d9f75844SAndroid Build Coastguard Worker return std::to_string(
272*d9f75844SAndroid Build Coastguard Worker event.runtime_setting().custom_render_processing_setting());
273*d9f75844SAndroid Build Coastguard Worker }),
274*d9f75844SAndroid Build Coastguard Worker RuntimeSettingWriter(
275*d9f75844SAndroid Build Coastguard Worker "CaptureFixedPostGain",
276*d9f75844SAndroid Build Coastguard Worker [](const Event& event) -> bool {
277*d9f75844SAndroid Build Coastguard Worker return event.runtime_setting().has_capture_fixed_post_gain();
278*d9f75844SAndroid Build Coastguard Worker },
279*d9f75844SAndroid Build Coastguard Worker [](const Event& event) -> std::string {
280*d9f75844SAndroid Build Coastguard Worker return std::to_string(
281*d9f75844SAndroid Build Coastguard Worker event.runtime_setting().capture_fixed_post_gain());
282*d9f75844SAndroid Build Coastguard Worker }),
283*d9f75844SAndroid Build Coastguard Worker RuntimeSettingWriter(
284*d9f75844SAndroid Build Coastguard Worker "PlayoutVolumeChange",
285*d9f75844SAndroid Build Coastguard Worker [](const Event& event) -> bool {
286*d9f75844SAndroid Build Coastguard Worker return event.runtime_setting().has_playout_volume_change();
287*d9f75844SAndroid Build Coastguard Worker },
288*d9f75844SAndroid Build Coastguard Worker [](const Event& event) -> std::string {
289*d9f75844SAndroid Build Coastguard Worker return std::to_string(
290*d9f75844SAndroid Build Coastguard Worker event.runtime_setting().playout_volume_change());
291*d9f75844SAndroid Build Coastguard Worker })};
292*d9f75844SAndroid Build Coastguard Worker }
293*d9f75844SAndroid Build Coastguard Worker
GetWavFileIndex(int init_index,int frame_count)294*d9f75844SAndroid Build Coastguard Worker std::string GetWavFileIndex(int init_index, int frame_count) {
295*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder suffix;
296*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_use_init_suffix)) {
297*d9f75844SAndroid Build Coastguard Worker suffix << "_" << init_index;
298*d9f75844SAndroid Build Coastguard Worker } else {
299*d9f75844SAndroid Build Coastguard Worker suffix << frame_count;
300*d9f75844SAndroid Build Coastguard Worker }
301*d9f75844SAndroid Build Coastguard Worker return suffix.str();
302*d9f75844SAndroid Build Coastguard Worker }
303*d9f75844SAndroid Build Coastguard Worker
304*d9f75844SAndroid Build Coastguard Worker } // namespace
305*d9f75844SAndroid Build Coastguard Worker
do_main(int argc,char * argv[])306*d9f75844SAndroid Build Coastguard Worker int do_main(int argc, char* argv[]) {
307*d9f75844SAndroid Build Coastguard Worker std::vector<char*> args = absl::ParseCommandLine(argc, argv);
308*d9f75844SAndroid Build Coastguard Worker std::string program_name = args[0];
309*d9f75844SAndroid Build Coastguard Worker std::string usage =
310*d9f75844SAndroid Build Coastguard Worker "Commandline tool to unpack audioproc debug files.\n"
311*d9f75844SAndroid Build Coastguard Worker "Example usage:\n" +
312*d9f75844SAndroid Build Coastguard Worker program_name + " debug_dump.pb\n";
313*d9f75844SAndroid Build Coastguard Worker
314*d9f75844SAndroid Build Coastguard Worker if (args.size() < 2) {
315*d9f75844SAndroid Build Coastguard Worker printf("%s", usage.c_str());
316*d9f75844SAndroid Build Coastguard Worker return 1;
317*d9f75844SAndroid Build Coastguard Worker }
318*d9f75844SAndroid Build Coastguard Worker
319*d9f75844SAndroid Build Coastguard Worker FILE* debug_file = OpenFile(args[1], "rb");
320*d9f75844SAndroid Build Coastguard Worker
321*d9f75844SAndroid Build Coastguard Worker Event event_msg;
322*d9f75844SAndroid Build Coastguard Worker int frame_count = 0;
323*d9f75844SAndroid Build Coastguard Worker int init_count = 0;
324*d9f75844SAndroid Build Coastguard Worker size_t reverse_samples_per_channel = 0;
325*d9f75844SAndroid Build Coastguard Worker size_t input_samples_per_channel = 0;
326*d9f75844SAndroid Build Coastguard Worker size_t output_samples_per_channel = 0;
327*d9f75844SAndroid Build Coastguard Worker size_t num_reverse_channels = 0;
328*d9f75844SAndroid Build Coastguard Worker size_t num_input_channels = 0;
329*d9f75844SAndroid Build Coastguard Worker size_t num_output_channels = 0;
330*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<WavWriter> reverse_wav_file;
331*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<WavWriter> input_wav_file;
332*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<WavWriter> output_wav_file;
333*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<RawFile> reverse_raw_file;
334*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<RawFile> input_raw_file;
335*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<RawFile> output_raw_file;
336*d9f75844SAndroid Build Coastguard Worker
337*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder callorder_raw_name;
338*d9f75844SAndroid Build Coastguard Worker callorder_raw_name << absl::GetFlag(FLAGS_callorder_file) << ".char";
339*d9f75844SAndroid Build Coastguard Worker FILE* callorder_char_file = WritingCallOrderFile()
340*d9f75844SAndroid Build Coastguard Worker ? OpenFile(callorder_raw_name.str(), "wb")
341*d9f75844SAndroid Build Coastguard Worker : nullptr;
342*d9f75844SAndroid Build Coastguard Worker FILE* settings_file = OpenFile(absl::GetFlag(FLAGS_settings_file), "wb");
343*d9f75844SAndroid Build Coastguard Worker
344*d9f75844SAndroid Build Coastguard Worker std::vector<RuntimeSettingWriter> runtime_setting_writers =
345*d9f75844SAndroid Build Coastguard Worker RuntimeSettingWriters();
346*d9f75844SAndroid Build Coastguard Worker
347*d9f75844SAndroid Build Coastguard Worker while (ReadMessageFromFile(debug_file, &event_msg)) {
348*d9f75844SAndroid Build Coastguard Worker if (event_msg.type() == Event::REVERSE_STREAM) {
349*d9f75844SAndroid Build Coastguard Worker if (!event_msg.has_reverse_stream()) {
350*d9f75844SAndroid Build Coastguard Worker printf("Corrupt input file: ReverseStream missing.\n");
351*d9f75844SAndroid Build Coastguard Worker return 1;
352*d9f75844SAndroid Build Coastguard Worker }
353*d9f75844SAndroid Build Coastguard Worker
354*d9f75844SAndroid Build Coastguard Worker const ReverseStream msg = event_msg.reverse_stream();
355*d9f75844SAndroid Build Coastguard Worker if (msg.has_data()) {
356*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_raw) && !reverse_raw_file) {
357*d9f75844SAndroid Build Coastguard Worker reverse_raw_file.reset(
358*d9f75844SAndroid Build Coastguard Worker new RawFile(absl::GetFlag(FLAGS_reverse_file) + ".pcm"));
359*d9f75844SAndroid Build Coastguard Worker }
360*d9f75844SAndroid Build Coastguard Worker // TODO(aluebs): Replace "num_reverse_channels *
361*d9f75844SAndroid Build Coastguard Worker // reverse_samples_per_channel" with "msg.data().size() /
362*d9f75844SAndroid Build Coastguard Worker // sizeof(int16_t)" and so on when this fix in audio_processing has made
363*d9f75844SAndroid Build Coastguard Worker // it into stable: https://webrtc-codereview.appspot.com/15299004/
364*d9f75844SAndroid Build Coastguard Worker WriteIntData(reinterpret_cast<const int16_t*>(msg.data().data()),
365*d9f75844SAndroid Build Coastguard Worker num_reverse_channels * reverse_samples_per_channel,
366*d9f75844SAndroid Build Coastguard Worker reverse_wav_file.get(), reverse_raw_file.get());
367*d9f75844SAndroid Build Coastguard Worker } else if (msg.channel_size() > 0) {
368*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_raw) && !reverse_raw_file) {
369*d9f75844SAndroid Build Coastguard Worker reverse_raw_file.reset(
370*d9f75844SAndroid Build Coastguard Worker new RawFile(absl::GetFlag(FLAGS_reverse_file) + ".float"));
371*d9f75844SAndroid Build Coastguard Worker }
372*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<const float*[]> data(
373*d9f75844SAndroid Build Coastguard Worker new const float*[num_reverse_channels]);
374*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < num_reverse_channels; ++i) {
375*d9f75844SAndroid Build Coastguard Worker data[i] = reinterpret_cast<const float*>(msg.channel(i).data());
376*d9f75844SAndroid Build Coastguard Worker }
377*d9f75844SAndroid Build Coastguard Worker WriteFloatData(data.get(), reverse_samples_per_channel,
378*d9f75844SAndroid Build Coastguard Worker num_reverse_channels, reverse_wav_file.get(),
379*d9f75844SAndroid Build Coastguard Worker reverse_raw_file.get());
380*d9f75844SAndroid Build Coastguard Worker }
381*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_full)) {
382*d9f75844SAndroid Build Coastguard Worker if (WritingCallOrderFile()) {
383*d9f75844SAndroid Build Coastguard Worker WriteCallOrderData(true /* render_call */, callorder_char_file,
384*d9f75844SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_callorder_file));
385*d9f75844SAndroid Build Coastguard Worker }
386*d9f75844SAndroid Build Coastguard Worker }
387*d9f75844SAndroid Build Coastguard Worker } else if (event_msg.type() == Event::STREAM) {
388*d9f75844SAndroid Build Coastguard Worker frame_count++;
389*d9f75844SAndroid Build Coastguard Worker if (!event_msg.has_stream()) {
390*d9f75844SAndroid Build Coastguard Worker printf("Corrupt input file: Stream missing.\n");
391*d9f75844SAndroid Build Coastguard Worker return 1;
392*d9f75844SAndroid Build Coastguard Worker }
393*d9f75844SAndroid Build Coastguard Worker
394*d9f75844SAndroid Build Coastguard Worker const Stream msg = event_msg.stream();
395*d9f75844SAndroid Build Coastguard Worker if (msg.has_input_data()) {
396*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_raw) && !input_raw_file) {
397*d9f75844SAndroid Build Coastguard Worker input_raw_file.reset(
398*d9f75844SAndroid Build Coastguard Worker new RawFile(absl::GetFlag(FLAGS_input_file) + ".pcm"));
399*d9f75844SAndroid Build Coastguard Worker }
400*d9f75844SAndroid Build Coastguard Worker WriteIntData(reinterpret_cast<const int16_t*>(msg.input_data().data()),
401*d9f75844SAndroid Build Coastguard Worker num_input_channels * input_samples_per_channel,
402*d9f75844SAndroid Build Coastguard Worker input_wav_file.get(), input_raw_file.get());
403*d9f75844SAndroid Build Coastguard Worker } else if (msg.input_channel_size() > 0) {
404*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_raw) && !input_raw_file) {
405*d9f75844SAndroid Build Coastguard Worker input_raw_file.reset(
406*d9f75844SAndroid Build Coastguard Worker new RawFile(absl::GetFlag(FLAGS_input_file) + ".float"));
407*d9f75844SAndroid Build Coastguard Worker }
408*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<const float*[]> data(
409*d9f75844SAndroid Build Coastguard Worker new const float*[num_input_channels]);
410*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < num_input_channels; ++i) {
411*d9f75844SAndroid Build Coastguard Worker data[i] = reinterpret_cast<const float*>(msg.input_channel(i).data());
412*d9f75844SAndroid Build Coastguard Worker }
413*d9f75844SAndroid Build Coastguard Worker WriteFloatData(data.get(), input_samples_per_channel,
414*d9f75844SAndroid Build Coastguard Worker num_input_channels, input_wav_file.get(),
415*d9f75844SAndroid Build Coastguard Worker input_raw_file.get());
416*d9f75844SAndroid Build Coastguard Worker }
417*d9f75844SAndroid Build Coastguard Worker
418*d9f75844SAndroid Build Coastguard Worker if (msg.has_output_data()) {
419*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_raw) && !output_raw_file) {
420*d9f75844SAndroid Build Coastguard Worker output_raw_file.reset(
421*d9f75844SAndroid Build Coastguard Worker new RawFile(absl::GetFlag(FLAGS_output_file) + ".pcm"));
422*d9f75844SAndroid Build Coastguard Worker }
423*d9f75844SAndroid Build Coastguard Worker WriteIntData(reinterpret_cast<const int16_t*>(msg.output_data().data()),
424*d9f75844SAndroid Build Coastguard Worker num_output_channels * output_samples_per_channel,
425*d9f75844SAndroid Build Coastguard Worker output_wav_file.get(), output_raw_file.get());
426*d9f75844SAndroid Build Coastguard Worker } else if (msg.output_channel_size() > 0) {
427*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_raw) && !output_raw_file) {
428*d9f75844SAndroid Build Coastguard Worker output_raw_file.reset(
429*d9f75844SAndroid Build Coastguard Worker new RawFile(absl::GetFlag(FLAGS_output_file) + ".float"));
430*d9f75844SAndroid Build Coastguard Worker }
431*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<const float*[]> data(
432*d9f75844SAndroid Build Coastguard Worker new const float*[num_output_channels]);
433*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < num_output_channels; ++i) {
434*d9f75844SAndroid Build Coastguard Worker data[i] =
435*d9f75844SAndroid Build Coastguard Worker reinterpret_cast<const float*>(msg.output_channel(i).data());
436*d9f75844SAndroid Build Coastguard Worker }
437*d9f75844SAndroid Build Coastguard Worker WriteFloatData(data.get(), output_samples_per_channel,
438*d9f75844SAndroid Build Coastguard Worker num_output_channels, output_wav_file.get(),
439*d9f75844SAndroid Build Coastguard Worker output_raw_file.get());
440*d9f75844SAndroid Build Coastguard Worker }
441*d9f75844SAndroid Build Coastguard Worker
442*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_full)) {
443*d9f75844SAndroid Build Coastguard Worker if (WritingCallOrderFile()) {
444*d9f75844SAndroid Build Coastguard Worker WriteCallOrderData(false /* render_call */, callorder_char_file,
445*d9f75844SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_callorder_file));
446*d9f75844SAndroid Build Coastguard Worker }
447*d9f75844SAndroid Build Coastguard Worker if (msg.has_delay()) {
448*d9f75844SAndroid Build Coastguard Worker static FILE* delay_file =
449*d9f75844SAndroid Build Coastguard Worker OpenFile(absl::GetFlag(FLAGS_delay_file), "wb");
450*d9f75844SAndroid Build Coastguard Worker int32_t delay = msg.delay();
451*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_text)) {
452*d9f75844SAndroid Build Coastguard Worker fprintf(delay_file, "%d\n", delay);
453*d9f75844SAndroid Build Coastguard Worker } else {
454*d9f75844SAndroid Build Coastguard Worker WriteData(&delay, sizeof(delay), delay_file,
455*d9f75844SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_delay_file));
456*d9f75844SAndroid Build Coastguard Worker }
457*d9f75844SAndroid Build Coastguard Worker }
458*d9f75844SAndroid Build Coastguard Worker
459*d9f75844SAndroid Build Coastguard Worker if (msg.has_drift()) {
460*d9f75844SAndroid Build Coastguard Worker static FILE* drift_file =
461*d9f75844SAndroid Build Coastguard Worker OpenFile(absl::GetFlag(FLAGS_drift_file), "wb");
462*d9f75844SAndroid Build Coastguard Worker int32_t drift = msg.drift();
463*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_text)) {
464*d9f75844SAndroid Build Coastguard Worker fprintf(drift_file, "%d\n", drift);
465*d9f75844SAndroid Build Coastguard Worker } else {
466*d9f75844SAndroid Build Coastguard Worker WriteData(&drift, sizeof(drift), drift_file,
467*d9f75844SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_drift_file));
468*d9f75844SAndroid Build Coastguard Worker }
469*d9f75844SAndroid Build Coastguard Worker }
470*d9f75844SAndroid Build Coastguard Worker
471*d9f75844SAndroid Build Coastguard Worker if (msg.has_applied_input_volume()) {
472*d9f75844SAndroid Build Coastguard Worker static FILE* level_file =
473*d9f75844SAndroid Build Coastguard Worker OpenFile(absl::GetFlag(FLAGS_level_file), "wb");
474*d9f75844SAndroid Build Coastguard Worker int32_t level = msg.applied_input_volume();
475*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_text)) {
476*d9f75844SAndroid Build Coastguard Worker fprintf(level_file, "%d\n", level);
477*d9f75844SAndroid Build Coastguard Worker } else {
478*d9f75844SAndroid Build Coastguard Worker WriteData(&level, sizeof(level), level_file,
479*d9f75844SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_level_file));
480*d9f75844SAndroid Build Coastguard Worker }
481*d9f75844SAndroid Build Coastguard Worker }
482*d9f75844SAndroid Build Coastguard Worker
483*d9f75844SAndroid Build Coastguard Worker if (msg.has_keypress()) {
484*d9f75844SAndroid Build Coastguard Worker static FILE* keypress_file =
485*d9f75844SAndroid Build Coastguard Worker OpenFile(absl::GetFlag(FLAGS_keypress_file), "wb");
486*d9f75844SAndroid Build Coastguard Worker bool keypress = msg.keypress();
487*d9f75844SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_text)) {
488*d9f75844SAndroid Build Coastguard Worker fprintf(keypress_file, "%d\n", keypress);
489*d9f75844SAndroid Build Coastguard Worker } else {
490*d9f75844SAndroid Build Coastguard Worker WriteData(&keypress, sizeof(keypress), keypress_file,
491*d9f75844SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_keypress_file));
492*d9f75844SAndroid Build Coastguard Worker }
493*d9f75844SAndroid Build Coastguard Worker }
494*d9f75844SAndroid Build Coastguard Worker }
495*d9f75844SAndroid Build Coastguard Worker } else if (event_msg.type() == Event::CONFIG) {
496*d9f75844SAndroid Build Coastguard Worker if (!event_msg.has_config()) {
497*d9f75844SAndroid Build Coastguard Worker printf("Corrupt input file: Config missing.\n");
498*d9f75844SAndroid Build Coastguard Worker return 1;
499*d9f75844SAndroid Build Coastguard Worker }
500*d9f75844SAndroid Build Coastguard Worker const audioproc::Config msg = event_msg.config();
501*d9f75844SAndroid Build Coastguard Worker
502*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, "APM re-config at frame: %d\n", frame_count);
503*d9f75844SAndroid Build Coastguard Worker
504*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(aec_enabled);
505*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(aec_delay_agnostic_enabled);
506*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(aec_drift_compensation_enabled);
507*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(aec_extended_filter_enabled);
508*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(aec_suppression_level);
509*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(aecm_enabled);
510*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(aecm_comfort_noise_enabled);
511*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(aecm_routing_mode);
512*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(agc_enabled);
513*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(agc_mode);
514*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(agc_limiter_enabled);
515*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(noise_robust_agc_enabled);
516*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(hpf_enabled);
517*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(ns_enabled);
518*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(ns_level);
519*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(transient_suppression_enabled);
520*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG(pre_amplifier_enabled);
521*d9f75844SAndroid Build Coastguard Worker PRINT_CONFIG_FLOAT(pre_amplifier_fixed_gain_factor);
522*d9f75844SAndroid Build Coastguard Worker
523*d9f75844SAndroid Build Coastguard Worker if (msg.has_experiments_description()) {
524*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " experiments_description: %s\n",
525*d9f75844SAndroid Build Coastguard Worker msg.experiments_description().c_str());
526*d9f75844SAndroid Build Coastguard Worker }
527*d9f75844SAndroid Build Coastguard Worker } else if (event_msg.type() == Event::INIT) {
528*d9f75844SAndroid Build Coastguard Worker if (!event_msg.has_init()) {
529*d9f75844SAndroid Build Coastguard Worker printf("Corrupt input file: Init missing.\n");
530*d9f75844SAndroid Build Coastguard Worker return 1;
531*d9f75844SAndroid Build Coastguard Worker }
532*d9f75844SAndroid Build Coastguard Worker
533*d9f75844SAndroid Build Coastguard Worker ++init_count;
534*d9f75844SAndroid Build Coastguard Worker const Init msg = event_msg.init();
535*d9f75844SAndroid Build Coastguard Worker // These should print out zeros if they're missing.
536*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, "Init #%d at frame: %d\n", init_count,
537*d9f75844SAndroid Build Coastguard Worker frame_count);
538*d9f75844SAndroid Build Coastguard Worker int input_sample_rate = msg.sample_rate();
539*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " Input sample rate: %d\n", input_sample_rate);
540*d9f75844SAndroid Build Coastguard Worker int output_sample_rate = msg.output_sample_rate();
541*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " Output sample rate: %d\n", output_sample_rate);
542*d9f75844SAndroid Build Coastguard Worker int reverse_sample_rate = msg.reverse_sample_rate();
543*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " Reverse sample rate: %d\n",
544*d9f75844SAndroid Build Coastguard Worker reverse_sample_rate);
545*d9f75844SAndroid Build Coastguard Worker num_input_channels = msg.num_input_channels();
546*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " Input channels: %zu\n", num_input_channels);
547*d9f75844SAndroid Build Coastguard Worker num_output_channels = msg.num_output_channels();
548*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " Output channels: %zu\n", num_output_channels);
549*d9f75844SAndroid Build Coastguard Worker num_reverse_channels = msg.num_reverse_channels();
550*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " Reverse channels: %zu\n", num_reverse_channels);
551*d9f75844SAndroid Build Coastguard Worker if (msg.has_timestamp_ms()) {
552*d9f75844SAndroid Build Coastguard Worker const int64_t timestamp = msg.timestamp_ms();
553*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, " Timestamp in millisecond: %" PRId64 "\n",
554*d9f75844SAndroid Build Coastguard Worker timestamp);
555*d9f75844SAndroid Build Coastguard Worker }
556*d9f75844SAndroid Build Coastguard Worker
557*d9f75844SAndroid Build Coastguard Worker fprintf(settings_file, "\n");
558*d9f75844SAndroid Build Coastguard Worker
559*d9f75844SAndroid Build Coastguard Worker if (reverse_sample_rate == 0) {
560*d9f75844SAndroid Build Coastguard Worker reverse_sample_rate = input_sample_rate;
561*d9f75844SAndroid Build Coastguard Worker }
562*d9f75844SAndroid Build Coastguard Worker if (output_sample_rate == 0) {
563*d9f75844SAndroid Build Coastguard Worker output_sample_rate = input_sample_rate;
564*d9f75844SAndroid Build Coastguard Worker }
565*d9f75844SAndroid Build Coastguard Worker
566*d9f75844SAndroid Build Coastguard Worker reverse_samples_per_channel =
567*d9f75844SAndroid Build Coastguard Worker static_cast<size_t>(reverse_sample_rate / 100);
568*d9f75844SAndroid Build Coastguard Worker input_samples_per_channel = static_cast<size_t>(input_sample_rate / 100);
569*d9f75844SAndroid Build Coastguard Worker output_samples_per_channel =
570*d9f75844SAndroid Build Coastguard Worker static_cast<size_t>(output_sample_rate / 100);
571*d9f75844SAndroid Build Coastguard Worker
572*d9f75844SAndroid Build Coastguard Worker if (!absl::GetFlag(FLAGS_raw)) {
573*d9f75844SAndroid Build Coastguard Worker // The WAV files need to be reset every time, because they cant change
574*d9f75844SAndroid Build Coastguard Worker // their sample rate or number of channels.
575*d9f75844SAndroid Build Coastguard Worker
576*d9f75844SAndroid Build Coastguard Worker std::string suffix = GetWavFileIndex(init_count, frame_count);
577*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder reverse_name;
578*d9f75844SAndroid Build Coastguard Worker reverse_name << absl::GetFlag(FLAGS_reverse_file) << suffix << ".wav";
579*d9f75844SAndroid Build Coastguard Worker reverse_wav_file.reset(new WavWriter(
580*d9f75844SAndroid Build Coastguard Worker reverse_name.str(), reverse_sample_rate, num_reverse_channels));
581*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder input_name;
582*d9f75844SAndroid Build Coastguard Worker input_name << absl::GetFlag(FLAGS_input_file) << suffix << ".wav";
583*d9f75844SAndroid Build Coastguard Worker input_wav_file.reset(new WavWriter(input_name.str(), input_sample_rate,
584*d9f75844SAndroid Build Coastguard Worker num_input_channels));
585*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder output_name;
586*d9f75844SAndroid Build Coastguard Worker output_name << absl::GetFlag(FLAGS_output_file) << suffix << ".wav";
587*d9f75844SAndroid Build Coastguard Worker output_wav_file.reset(new WavWriter(
588*d9f75844SAndroid Build Coastguard Worker output_name.str(), output_sample_rate, num_output_channels));
589*d9f75844SAndroid Build Coastguard Worker
590*d9f75844SAndroid Build Coastguard Worker if (WritingCallOrderFile()) {
591*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder callorder_name;
592*d9f75844SAndroid Build Coastguard Worker callorder_name << absl::GetFlag(FLAGS_callorder_file) << suffix
593*d9f75844SAndroid Build Coastguard Worker << ".char";
594*d9f75844SAndroid Build Coastguard Worker callorder_char_file = OpenFile(callorder_name.str(), "wb");
595*d9f75844SAndroid Build Coastguard Worker }
596*d9f75844SAndroid Build Coastguard Worker
597*d9f75844SAndroid Build Coastguard Worker if (WritingRuntimeSettingFiles()) {
598*d9f75844SAndroid Build Coastguard Worker for (RuntimeSettingWriter& writer : runtime_setting_writers) {
599*d9f75844SAndroid Build Coastguard Worker writer.HandleInitEvent(frame_count);
600*d9f75844SAndroid Build Coastguard Worker }
601*d9f75844SAndroid Build Coastguard Worker }
602*d9f75844SAndroid Build Coastguard Worker }
603*d9f75844SAndroid Build Coastguard Worker } else if (event_msg.type() == Event::RUNTIME_SETTING) {
604*d9f75844SAndroid Build Coastguard Worker if (WritingRuntimeSettingFiles()) {
605*d9f75844SAndroid Build Coastguard Worker for (RuntimeSettingWriter& writer : runtime_setting_writers) {
606*d9f75844SAndroid Build Coastguard Worker if (writer.IsExporterFor(event_msg)) {
607*d9f75844SAndroid Build Coastguard Worker writer.WriteEvent(event_msg, frame_count);
608*d9f75844SAndroid Build Coastguard Worker }
609*d9f75844SAndroid Build Coastguard Worker }
610*d9f75844SAndroid Build Coastguard Worker }
611*d9f75844SAndroid Build Coastguard Worker }
612*d9f75844SAndroid Build Coastguard Worker }
613*d9f75844SAndroid Build Coastguard Worker
614*d9f75844SAndroid Build Coastguard Worker return 0;
615*d9f75844SAndroid Build Coastguard Worker }
616*d9f75844SAndroid Build Coastguard Worker
617*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
618*d9f75844SAndroid Build Coastguard Worker
main(int argc,char * argv[])619*d9f75844SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
620*d9f75844SAndroid Build Coastguard Worker return webrtc::do_main(argc, argv);
621*d9f75844SAndroid Build Coastguard Worker }
622