OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 // Commandline tool to unpack audioproc debug files. | 11 // Commandline tool to unpack audioproc debug files. |
12 // | 12 // |
13 // The debug files are dumped as protobuf blobs. For analysis, it's necessary | 13 // The debug files are dumped as protobuf blobs. For analysis, it's necessary |
14 // to unpack the file into its component parts: audio and other data. | 14 // to unpack the file into its component parts: audio and other data. |
15 | 15 |
16 #include <stdio.h> | 16 #include <stdio.h> |
17 | 17 |
18 #include <memory> | 18 #include <memory> |
19 | 19 |
20 #include "gflags/gflags.h" | |
21 #include "webrtc/modules/audio_processing/test/protobuf_utils.h" | 20 #include "webrtc/modules/audio_processing/test/protobuf_utils.h" |
22 #include "webrtc/modules/audio_processing/test/test_utils.h" | 21 #include "webrtc/modules/audio_processing/test/test_utils.h" |
| 22 #include "webrtc/rtc_base/flags.h" |
23 #include "webrtc/rtc_base/format_macros.h" | 23 #include "webrtc/rtc_base/format_macros.h" |
24 #include "webrtc/rtc_base/ignore_wundef.h" | 24 #include "webrtc/rtc_base/ignore_wundef.h" |
25 #include "webrtc/typedefs.h" | 25 #include "webrtc/typedefs.h" |
26 | 26 |
27 RTC_PUSH_IGNORING_WUNDEF() | 27 RTC_PUSH_IGNORING_WUNDEF() |
28 #include "webrtc/modules/audio_processing/debug.pb.h" | 28 #include "webrtc/modules/audio_processing/debug.pb.h" |
29 RTC_POP_IGNORING_WUNDEF() | 29 RTC_POP_IGNORING_WUNDEF() |
30 | 30 |
31 // TODO(andrew): unpack more of the data. | 31 // TODO(andrew): unpack more of the data. |
32 DEFINE_string(input_file, "input", "The name of the input stream file."); | 32 DEFINE_string(input_file, "input", "The name of the input stream file."); |
33 DEFINE_string(output_file, "ref_out", | 33 DEFINE_string(output_file, "ref_out", |
34 "The name of the reference output stream file."); | 34 "The name of the reference output stream file."); |
35 DEFINE_string(reverse_file, "reverse", | 35 DEFINE_string(reverse_file, "reverse", |
36 "The name of the reverse input stream file."); | 36 "The name of the reverse input stream file."); |
37 DEFINE_string(delay_file, "delay.int32", "The name of the delay file."); | 37 DEFINE_string(delay_file, "delay.int32", "The name of the delay file."); |
38 DEFINE_string(drift_file, "drift.int32", "The name of the drift file."); | 38 DEFINE_string(drift_file, "drift.int32", "The name of the drift file."); |
39 DEFINE_string(level_file, "level.int32", "The name of the level file."); | 39 DEFINE_string(level_file, "level.int32", "The name of the level file."); |
40 DEFINE_string(keypress_file, "keypress.bool", "The name of the keypress file."); | 40 DEFINE_string(keypress_file, "keypress.bool", "The name of the keypress file."); |
41 DEFINE_string(settings_file, "settings.txt", "The name of the settings file."); | 41 DEFINE_string(settings_file, "settings.txt", "The name of the settings file."); |
42 DEFINE_bool(full, false, | 42 DEFINE_bool(full, false, |
43 "Unpack the full set of files (normally not needed)."); | 43 "Unpack the full set of files (normally not needed)."); |
44 DEFINE_bool(raw, false, "Write raw data instead of a WAV file."); | 44 DEFINE_bool(raw, false, "Write raw data instead of a WAV file."); |
45 DEFINE_bool(text, | 45 DEFINE_bool(text, |
46 false, | 46 false, |
47 "Write non-audio files as text files instead of binary files."); | 47 "Write non-audio files as text files instead of binary files."); |
| 48 DEFINE_bool(help, false, "Print this message."); |
48 | 49 |
49 #define PRINT_CONFIG(field_name) \ | 50 #define PRINT_CONFIG(field_name) \ |
50 if (msg.has_##field_name()) { \ | 51 if (msg.has_##field_name()) { \ |
51 fprintf(settings_file, " " #field_name ": %d\n", msg.field_name()); \ | 52 fprintf(settings_file, " " #field_name ": %d\n", msg.field_name()); \ |
52 } | 53 } |
53 | 54 |
54 namespace webrtc { | 55 namespace webrtc { |
55 | 56 |
56 using audioproc::Event; | 57 using audioproc::Event; |
57 using audioproc::ReverseStream; | 58 using audioproc::ReverseStream; |
58 using audioproc::Stream; | 59 using audioproc::Stream; |
59 using audioproc::Init; | 60 using audioproc::Init; |
60 | 61 |
61 void WriteData(const void* data, size_t size, FILE* file, | 62 void WriteData(const void* data, size_t size, FILE* file, |
62 const std::string& filename) { | 63 const std::string& filename) { |
63 if (fwrite(data, size, 1, file) != 1) { | 64 if (fwrite(data, size, 1, file) != 1) { |
64 printf("Error when writing to %s\n", filename.c_str()); | 65 printf("Error when writing to %s\n", filename.c_str()); |
65 exit(1); | 66 exit(1); |
66 } | 67 } |
67 } | 68 } |
68 | 69 |
69 int do_main(int argc, char* argv[]) { | 70 int do_main(int argc, char* argv[]) { |
70 std::string program_name = argv[0]; | 71 std::string program_name = argv[0]; |
71 std::string usage = "Commandline tool to unpack audioproc debug files.\n" | 72 std::string usage = "Commandline tool to unpack audioproc debug files.\n" |
72 "Example usage:\n" + program_name + " debug_dump.pb\n"; | 73 "Example usage:\n" + program_name + " debug_dump.pb\n"; |
73 google::SetUsageMessage(usage); | |
74 google::ParseCommandLineFlags(&argc, &argv, true); | |
75 | 74 |
76 if (argc < 2) { | 75 if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true) || |
77 printf("%s", google::ProgramUsage()); | 76 FLAG_help || argc < 2) { |
| 77 printf("%s", usage.c_str()); |
| 78 if (FLAG_help) { |
| 79 rtc::FlagList::Print(nullptr, false); |
| 80 return 0; |
| 81 } |
78 return 1; | 82 return 1; |
79 } | 83 } |
80 | 84 |
81 FILE* debug_file = OpenFile(argv[1], "rb"); | 85 FILE* debug_file = OpenFile(argv[1], "rb"); |
82 | 86 |
83 Event event_msg; | 87 Event event_msg; |
84 int frame_count = 0; | 88 int frame_count = 0; |
85 size_t reverse_samples_per_channel = 0; | 89 size_t reverse_samples_per_channel = 0; |
86 size_t input_samples_per_channel = 0; | 90 size_t input_samples_per_channel = 0; |
87 size_t output_samples_per_channel = 0; | 91 size_t output_samples_per_channel = 0; |
88 size_t num_reverse_channels = 0; | 92 size_t num_reverse_channels = 0; |
89 size_t num_input_channels = 0; | 93 size_t num_input_channels = 0; |
90 size_t num_output_channels = 0; | 94 size_t num_output_channels = 0; |
91 std::unique_ptr<WavWriter> reverse_wav_file; | 95 std::unique_ptr<WavWriter> reverse_wav_file; |
92 std::unique_ptr<WavWriter> input_wav_file; | 96 std::unique_ptr<WavWriter> input_wav_file; |
93 std::unique_ptr<WavWriter> output_wav_file; | 97 std::unique_ptr<WavWriter> output_wav_file; |
94 std::unique_ptr<RawFile> reverse_raw_file; | 98 std::unique_ptr<RawFile> reverse_raw_file; |
95 std::unique_ptr<RawFile> input_raw_file; | 99 std::unique_ptr<RawFile> input_raw_file; |
96 std::unique_ptr<RawFile> output_raw_file; | 100 std::unique_ptr<RawFile> output_raw_file; |
97 | 101 |
98 FILE* settings_file = OpenFile(FLAGS_settings_file, "wb"); | 102 FILE* settings_file = OpenFile(FLAG_settings_file, "wb"); |
99 | 103 |
100 while (ReadMessageFromFile(debug_file, &event_msg)) { | 104 while (ReadMessageFromFile(debug_file, &event_msg)) { |
101 if (event_msg.type() == Event::REVERSE_STREAM) { | 105 if (event_msg.type() == Event::REVERSE_STREAM) { |
102 if (!event_msg.has_reverse_stream()) { | 106 if (!event_msg.has_reverse_stream()) { |
103 printf("Corrupt input file: ReverseStream missing.\n"); | 107 printf("Corrupt input file: ReverseStream missing.\n"); |
104 return 1; | 108 return 1; |
105 } | 109 } |
106 | 110 |
107 const ReverseStream msg = event_msg.reverse_stream(); | 111 const ReverseStream msg = event_msg.reverse_stream(); |
108 if (msg.has_data()) { | 112 if (msg.has_data()) { |
109 if (FLAGS_raw && !reverse_raw_file) { | 113 if (FLAG_raw && !reverse_raw_file) { |
110 reverse_raw_file.reset(new RawFile(FLAGS_reverse_file + ".pcm")); | 114 reverse_raw_file.reset(new RawFile(std::string(FLAG_reverse_file) + |
| 115 ".pcm")); |
111 } | 116 } |
112 // TODO(aluebs): Replace "num_reverse_channels * | 117 // TODO(aluebs): Replace "num_reverse_channels * |
113 // reverse_samples_per_channel" with "msg.data().size() / | 118 // reverse_samples_per_channel" with "msg.data().size() / |
114 // sizeof(int16_t)" and so on when this fix in audio_processing has made | 119 // sizeof(int16_t)" and so on when this fix in audio_processing has made |
115 // it into stable: https://webrtc-codereview.appspot.com/15299004/ | 120 // it into stable: https://webrtc-codereview.appspot.com/15299004/ |
116 WriteIntData(reinterpret_cast<const int16_t*>(msg.data().data()), | 121 WriteIntData(reinterpret_cast<const int16_t*>(msg.data().data()), |
117 num_reverse_channels * reverse_samples_per_channel, | 122 num_reverse_channels * reverse_samples_per_channel, |
118 reverse_wav_file.get(), | 123 reverse_wav_file.get(), |
119 reverse_raw_file.get()); | 124 reverse_raw_file.get()); |
120 } else if (msg.channel_size() > 0) { | 125 } else if (msg.channel_size() > 0) { |
121 if (FLAGS_raw && !reverse_raw_file) { | 126 if (FLAG_raw && !reverse_raw_file) { |
122 reverse_raw_file.reset(new RawFile(FLAGS_reverse_file + ".float")); | 127 reverse_raw_file.reset(new RawFile(std::string(FLAG_reverse_file) + |
| 128 ".float")); |
123 } | 129 } |
124 std::unique_ptr<const float* []> data( | 130 std::unique_ptr<const float* []> data( |
125 new const float* [num_reverse_channels]); | 131 new const float* [num_reverse_channels]); |
126 for (size_t i = 0; i < num_reverse_channels; ++i) { | 132 for (size_t i = 0; i < num_reverse_channels; ++i) { |
127 data[i] = reinterpret_cast<const float*>(msg.channel(i).data()); | 133 data[i] = reinterpret_cast<const float*>(msg.channel(i).data()); |
128 } | 134 } |
129 WriteFloatData(data.get(), | 135 WriteFloatData(data.get(), |
130 reverse_samples_per_channel, | 136 reverse_samples_per_channel, |
131 num_reverse_channels, | 137 num_reverse_channels, |
132 reverse_wav_file.get(), | 138 reverse_wav_file.get(), |
133 reverse_raw_file.get()); | 139 reverse_raw_file.get()); |
134 } | 140 } |
135 } else if (event_msg.type() == Event::STREAM) { | 141 } else if (event_msg.type() == Event::STREAM) { |
136 frame_count++; | 142 frame_count++; |
137 if (!event_msg.has_stream()) { | 143 if (!event_msg.has_stream()) { |
138 printf("Corrupt input file: Stream missing.\n"); | 144 printf("Corrupt input file: Stream missing.\n"); |
139 return 1; | 145 return 1; |
140 } | 146 } |
141 | 147 |
142 const Stream msg = event_msg.stream(); | 148 const Stream msg = event_msg.stream(); |
143 if (msg.has_input_data()) { | 149 if (msg.has_input_data()) { |
144 if (FLAGS_raw && !input_raw_file) { | 150 if (FLAG_raw && !input_raw_file) { |
145 input_raw_file.reset(new RawFile(FLAGS_input_file + ".pcm")); | 151 input_raw_file.reset(new RawFile(std::string(FLAG_input_file) + |
| 152 ".pcm")); |
146 } | 153 } |
147 WriteIntData(reinterpret_cast<const int16_t*>(msg.input_data().data()), | 154 WriteIntData(reinterpret_cast<const int16_t*>(msg.input_data().data()), |
148 num_input_channels * input_samples_per_channel, | 155 num_input_channels * input_samples_per_channel, |
149 input_wav_file.get(), | 156 input_wav_file.get(), |
150 input_raw_file.get()); | 157 input_raw_file.get()); |
151 } else if (msg.input_channel_size() > 0) { | 158 } else if (msg.input_channel_size() > 0) { |
152 if (FLAGS_raw && !input_raw_file) { | 159 if (FLAG_raw && !input_raw_file) { |
153 input_raw_file.reset(new RawFile(FLAGS_input_file + ".float")); | 160 input_raw_file.reset(new RawFile(std::string(FLAG_input_file) + |
| 161 ".float")); |
154 } | 162 } |
155 std::unique_ptr<const float* []> data( | 163 std::unique_ptr<const float* []> data( |
156 new const float* [num_input_channels]); | 164 new const float* [num_input_channels]); |
157 for (size_t i = 0; i < num_input_channels; ++i) { | 165 for (size_t i = 0; i < num_input_channels; ++i) { |
158 data[i] = reinterpret_cast<const float*>(msg.input_channel(i).data()); | 166 data[i] = reinterpret_cast<const float*>(msg.input_channel(i).data()); |
159 } | 167 } |
160 WriteFloatData(data.get(), | 168 WriteFloatData(data.get(), |
161 input_samples_per_channel, | 169 input_samples_per_channel, |
162 num_input_channels, | 170 num_input_channels, |
163 input_wav_file.get(), | 171 input_wav_file.get(), |
164 input_raw_file.get()); | 172 input_raw_file.get()); |
165 } | 173 } |
166 | 174 |
167 if (msg.has_output_data()) { | 175 if (msg.has_output_data()) { |
168 if (FLAGS_raw && !output_raw_file) { | 176 if (FLAG_raw && !output_raw_file) { |
169 output_raw_file.reset(new RawFile(FLAGS_output_file + ".pcm")); | 177 output_raw_file.reset(new RawFile(std::string(FLAG_output_file) + |
| 178 ".pcm")); |
170 } | 179 } |
171 WriteIntData(reinterpret_cast<const int16_t*>(msg.output_data().data()), | 180 WriteIntData(reinterpret_cast<const int16_t*>(msg.output_data().data()), |
172 num_output_channels * output_samples_per_channel, | 181 num_output_channels * output_samples_per_channel, |
173 output_wav_file.get(), | 182 output_wav_file.get(), |
174 output_raw_file.get()); | 183 output_raw_file.get()); |
175 } else if (msg.output_channel_size() > 0) { | 184 } else if (msg.output_channel_size() > 0) { |
176 if (FLAGS_raw && !output_raw_file) { | 185 if (FLAG_raw && !output_raw_file) { |
177 output_raw_file.reset(new RawFile(FLAGS_output_file + ".float")); | 186 output_raw_file.reset(new RawFile(std::string(FLAG_output_file) + |
| 187 ".float")); |
178 } | 188 } |
179 std::unique_ptr<const float* []> data( | 189 std::unique_ptr<const float* []> data( |
180 new const float* [num_output_channels]); | 190 new const float* [num_output_channels]); |
181 for (size_t i = 0; i < num_output_channels; ++i) { | 191 for (size_t i = 0; i < num_output_channels; ++i) { |
182 data[i] = | 192 data[i] = |
183 reinterpret_cast<const float*>(msg.output_channel(i).data()); | 193 reinterpret_cast<const float*>(msg.output_channel(i).data()); |
184 } | 194 } |
185 WriteFloatData(data.get(), | 195 WriteFloatData(data.get(), |
186 output_samples_per_channel, | 196 output_samples_per_channel, |
187 num_output_channels, | 197 num_output_channels, |
188 output_wav_file.get(), | 198 output_wav_file.get(), |
189 output_raw_file.get()); | 199 output_raw_file.get()); |
190 } | 200 } |
191 | 201 |
192 if (FLAGS_full) { | 202 if (FLAG_full) { |
193 if (msg.has_delay()) { | 203 if (msg.has_delay()) { |
194 static FILE* delay_file = OpenFile(FLAGS_delay_file, "wb"); | 204 static FILE* delay_file = OpenFile(FLAG_delay_file, "wb"); |
195 int32_t delay = msg.delay(); | 205 int32_t delay = msg.delay(); |
196 if (FLAGS_text) { | 206 if (FLAG_text) { |
197 fprintf(delay_file, "%d\n", delay); | 207 fprintf(delay_file, "%d\n", delay); |
198 } else { | 208 } else { |
199 WriteData(&delay, sizeof(delay), delay_file, FLAGS_delay_file); | 209 WriteData(&delay, sizeof(delay), delay_file, FLAG_delay_file); |
200 } | 210 } |
201 } | 211 } |
202 | 212 |
203 if (msg.has_drift()) { | 213 if (msg.has_drift()) { |
204 static FILE* drift_file = OpenFile(FLAGS_drift_file, "wb"); | 214 static FILE* drift_file = OpenFile(FLAG_drift_file, "wb"); |
205 int32_t drift = msg.drift(); | 215 int32_t drift = msg.drift(); |
206 if (FLAGS_text) { | 216 if (FLAG_text) { |
207 fprintf(drift_file, "%d\n", drift); | 217 fprintf(drift_file, "%d\n", drift); |
208 } else { | 218 } else { |
209 WriteData(&drift, sizeof(drift), drift_file, FLAGS_drift_file); | 219 WriteData(&drift, sizeof(drift), drift_file, FLAG_drift_file); |
210 } | 220 } |
211 } | 221 } |
212 | 222 |
213 if (msg.has_level()) { | 223 if (msg.has_level()) { |
214 static FILE* level_file = OpenFile(FLAGS_level_file, "wb"); | 224 static FILE* level_file = OpenFile(FLAG_level_file, "wb"); |
215 int32_t level = msg.level(); | 225 int32_t level = msg.level(); |
216 if (FLAGS_text) { | 226 if (FLAG_text) { |
217 fprintf(level_file, "%d\n", level); | 227 fprintf(level_file, "%d\n", level); |
218 } else { | 228 } else { |
219 WriteData(&level, sizeof(level), level_file, FLAGS_level_file); | 229 WriteData(&level, sizeof(level), level_file, FLAG_level_file); |
220 } | 230 } |
221 } | 231 } |
222 | 232 |
223 if (msg.has_keypress()) { | 233 if (msg.has_keypress()) { |
224 static FILE* keypress_file = OpenFile(FLAGS_keypress_file, "wb"); | 234 static FILE* keypress_file = OpenFile(FLAG_keypress_file, "wb"); |
225 bool keypress = msg.keypress(); | 235 bool keypress = msg.keypress(); |
226 if (FLAGS_text) { | 236 if (FLAG_text) { |
227 fprintf(keypress_file, "%d\n", keypress); | 237 fprintf(keypress_file, "%d\n", keypress); |
228 } else { | 238 } else { |
229 WriteData(&keypress, sizeof(keypress), keypress_file, | 239 WriteData(&keypress, sizeof(keypress), keypress_file, |
230 FLAGS_keypress_file); | 240 FLAG_keypress_file); |
231 } | 241 } |
232 } | 242 } |
233 } | 243 } |
234 } else if (event_msg.type() == Event::CONFIG) { | 244 } else if (event_msg.type() == Event::CONFIG) { |
235 if (!event_msg.has_config()) { | 245 if (!event_msg.has_config()) { |
236 printf("Corrupt input file: Config missing.\n"); | 246 printf("Corrupt input file: Config missing.\n"); |
237 return 1; | 247 return 1; |
238 } | 248 } |
239 const audioproc::Config msg = event_msg.config(); | 249 const audioproc::Config msg = event_msg.config(); |
240 | 250 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 output_sample_rate = input_sample_rate; | 307 output_sample_rate = input_sample_rate; |
298 } | 308 } |
299 | 309 |
300 reverse_samples_per_channel = | 310 reverse_samples_per_channel = |
301 static_cast<size_t>(reverse_sample_rate / 100); | 311 static_cast<size_t>(reverse_sample_rate / 100); |
302 input_samples_per_channel = | 312 input_samples_per_channel = |
303 static_cast<size_t>(input_sample_rate / 100); | 313 static_cast<size_t>(input_sample_rate / 100); |
304 output_samples_per_channel = | 314 output_samples_per_channel = |
305 static_cast<size_t>(output_sample_rate / 100); | 315 static_cast<size_t>(output_sample_rate / 100); |
306 | 316 |
307 if (!FLAGS_raw) { | 317 if (!FLAG_raw) { |
308 // The WAV files need to be reset every time, because they cant change | 318 // The WAV files need to be reset every time, because they cant change |
309 // their sample rate or number of channels. | 319 // their sample rate or number of channels. |
310 std::stringstream reverse_name; | 320 std::stringstream reverse_name; |
311 reverse_name << FLAGS_reverse_file << frame_count << ".wav"; | 321 reverse_name << FLAG_reverse_file << frame_count << ".wav"; |
312 reverse_wav_file.reset(new WavWriter(reverse_name.str(), | 322 reverse_wav_file.reset(new WavWriter(reverse_name.str(), |
313 reverse_sample_rate, | 323 reverse_sample_rate, |
314 num_reverse_channels)); | 324 num_reverse_channels)); |
315 std::stringstream input_name; | 325 std::stringstream input_name; |
316 input_name << FLAGS_input_file << frame_count << ".wav"; | 326 input_name << FLAG_input_file << frame_count << ".wav"; |
317 input_wav_file.reset(new WavWriter(input_name.str(), | 327 input_wav_file.reset(new WavWriter(input_name.str(), |
318 input_sample_rate, | 328 input_sample_rate, |
319 num_input_channels)); | 329 num_input_channels)); |
320 std::stringstream output_name; | 330 std::stringstream output_name; |
321 output_name << FLAGS_output_file << frame_count << ".wav"; | 331 output_name << FLAG_output_file << frame_count << ".wav"; |
322 output_wav_file.reset(new WavWriter(output_name.str(), | 332 output_wav_file.reset(new WavWriter(output_name.str(), |
323 output_sample_rate, | 333 output_sample_rate, |
324 num_output_channels)); | 334 num_output_channels)); |
325 } | 335 } |
326 } | 336 } |
327 } | 337 } |
328 | 338 |
329 return 0; | 339 return 0; |
330 } | 340 } |
331 | 341 |
332 } // namespace webrtc | 342 } // namespace webrtc |
333 | 343 |
334 int main(int argc, char* argv[]) { | 344 int main(int argc, char* argv[]) { |
335 return webrtc::do_main(argc, argv); | 345 return webrtc::do_main(argc, argv); |
336 } | 346 } |
OLD | NEW |