blob: 001fbf796e55f9a2e75f6c9b4444a4d84209e7c7 [file] [log] [blame]
peahb46083e2016-05-03 07:01:18 -07001/*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_
12#define MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_
peahb46083e2016-05-03 07:01:18 -070013
Yves Gerey988cc082018-10-23 12:03:01 +020014#include <stdint.h>
peahb46083e2016-05-03 07:01:18 -070015#include <stdio.h>
Alessio Bazzica4bc60452018-11-20 12:44:15 +010016#include <string.h>
peahb46083e2016-05-03 07:01:18 -070017
Alessio Bazzica4bc60452018-11-20 12:44:15 +010018#include <string>
Per Åhgrenf0c449e2018-10-23 20:17:18 +020019#if WEBRTC_APM_DEBUG_DUMP == 1
20#include <unordered_map>
21#endif
22
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "api/array_view.h"
Per Åhgrenf0c449e2018-10-23 20:17:18 +020024#if WEBRTC_APM_DEBUG_DUMP == 1
25#include "common_audio/wav_file.h"
Alessio Bazzica4bc60452018-11-20 12:44:15 +010026#include "rtc_base/checks.h"
Per Åhgrenf0c449e2018-10-23 20:17:18 +020027#endif
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/constructor_magic.h"
peahb46083e2016-05-03 07:01:18 -070029
30// Check to verify that the define is properly set.
peahf28a3892016-09-01 08:58:21 -070031#if !defined(WEBRTC_APM_DEBUG_DUMP) || \
32 (WEBRTC_APM_DEBUG_DUMP != 0 && WEBRTC_APM_DEBUG_DUMP != 1)
33#error "Set WEBRTC_APM_DEBUG_DUMP to either 0 or 1"
peahb46083e2016-05-03 07:01:18 -070034#endif
35
36namespace webrtc {
37
peahf28a3892016-09-01 08:58:21 -070038#if WEBRTC_APM_DEBUG_DUMP == 1
peahb46083e2016-05-03 07:01:18 -070039// Functor used to use as a custom deleter in the map of file pointers to raw
40// files.
41struct RawFileCloseFunctor {
42 void operator()(FILE* f) const { fclose(f); }
43};
44#endif
45
46// Class that handles dumping of variables into files.
47class ApmDataDumper {
48 public:
peahf8f754a2016-08-30 10:31:45 -070049 // Constructor that takes an instance index that may
50 // be used to distinguish data dumped from different
51 // instances of the code.
52 explicit ApmDataDumper(int instance_index);
53
54 ~ApmDataDumper();
peahb46083e2016-05-03 07:01:18 -070055
Per Åhgren7a95e0f2018-10-25 09:56:49 +020056 // Activates or deactivate the dumping functionality.
57 static void SetActivated(bool activated) {
58#if WEBRTC_APM_DEBUG_DUMP == 1
59 recording_activated_ = activated;
60#endif
61 }
62
Alessio Bazzica4bc60452018-11-20 12:44:15 +010063 // Set an optional output directory.
64 static void SetOutputDirectory(const std::string& output_dir) {
65#if WEBRTC_APM_DEBUG_DUMP == 1
66 RTC_CHECK_LT(output_dir.size(), kOutputDirMaxLength);
67 strncpy(output_dir_, output_dir.c_str(), output_dir.size());
68#endif
69 }
70
peahb46083e2016-05-03 07:01:18 -070071 // Reinitializes the data dumping such that new versions
72 // of all files being dumped to are created.
73 void InitiateNewSetOfRecordings() {
peahf28a3892016-09-01 08:58:21 -070074#if WEBRTC_APM_DEBUG_DUMP == 1
peahb46083e2016-05-03 07:01:18 -070075 ++recording_set_index_;
76#endif
77 }
78
79 // Methods for performing dumping of data of various types into
80 // various formats.
peah69221db2017-01-27 03:28:19 -080081 void DumpRaw(const char* name, double v) {
82#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +020083 if (recording_activated_) {
84 FILE* file = GetRawFile(name);
85 fwrite(&v, sizeof(v), 1, file);
86 }
peah69221db2017-01-27 03:28:19 -080087#endif
88 }
89
90 void DumpRaw(const char* name, size_t v_length, const double* v) {
91#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +020092 if (recording_activated_) {
93 FILE* file = GetRawFile(name);
94 fwrite(v, sizeof(v[0]), v_length, file);
95 }
peah69221db2017-01-27 03:28:19 -080096#endif
97 }
98
99 void DumpRaw(const char* name, rtc::ArrayView<const double> v) {
100#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200101 if (recording_activated_) {
102 DumpRaw(name, v.size(), v.data());
103 }
peah69221db2017-01-27 03:28:19 -0800104#endif
105 }
106
107 void DumpRaw(const char* name, float v) {
108#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200109 if (recording_activated_) {
110 FILE* file = GetRawFile(name);
111 fwrite(&v, sizeof(v), 1, file);
112 }
peah69221db2017-01-27 03:28:19 -0800113#endif
114 }
115
116 void DumpRaw(const char* name, size_t v_length, const float* v) {
peahf28a3892016-09-01 08:58:21 -0700117#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200118 if (recording_activated_) {
119 FILE* file = GetRawFile(name);
120 fwrite(v, sizeof(v[0]), v_length, file);
121 }
peahb46083e2016-05-03 07:01:18 -0700122#endif
123 }
124
125 void DumpRaw(const char* name, rtc::ArrayView<const float> v) {
peahf28a3892016-09-01 08:58:21 -0700126#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200127 if (recording_activated_) {
128 DumpRaw(name, v.size(), v.data());
129 }
peahb46083e2016-05-03 07:01:18 -0700130#endif
131 }
132
peah69221db2017-01-27 03:28:19 -0800133 void DumpRaw(const char* name, bool v) {
134#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200135 if (recording_activated_) {
136 DumpRaw(name, static_cast<int16_t>(v));
137 }
peah69221db2017-01-27 03:28:19 -0800138#endif
139 }
140
141 void DumpRaw(const char* name, size_t v_length, const bool* v) {
peahf28a3892016-09-01 08:58:21 -0700142#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200143 if (recording_activated_) {
144 FILE* file = GetRawFile(name);
145 for (size_t k = 0; k < v_length; ++k) {
146 int16_t value = static_cast<int16_t>(v[k]);
147 fwrite(&value, sizeof(value), 1, file);
148 }
peahca4cac72016-06-29 15:26:12 -0700149 }
150#endif
151 }
152
153 void DumpRaw(const char* name, rtc::ArrayView<const bool> v) {
peahf28a3892016-09-01 08:58:21 -0700154#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200155 if (recording_activated_) {
156 DumpRaw(name, v.size(), v.data());
157 }
peahca4cac72016-06-29 15:26:12 -0700158#endif
159 }
160
peah69221db2017-01-27 03:28:19 -0800161 void DumpRaw(const char* name, int16_t v) {
162#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200163 if (recording_activated_) {
164 FILE* file = GetRawFile(name);
165 fwrite(&v, sizeof(v), 1, file);
166 }
peah69221db2017-01-27 03:28:19 -0800167#endif
168 }
169
170 void DumpRaw(const char* name, size_t v_length, const int16_t* v) {
peahf28a3892016-09-01 08:58:21 -0700171#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200172 if (recording_activated_) {
173 FILE* file = GetRawFile(name);
174 fwrite(v, sizeof(v[0]), v_length, file);
175 }
peah3f08dc62016-05-05 03:03:55 -0700176#endif
177 }
178
179 void DumpRaw(const char* name, rtc::ArrayView<const int16_t> v) {
peahf28a3892016-09-01 08:58:21 -0700180#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200181 if (recording_activated_) {
182 DumpRaw(name, v.size(), v.data());
183 }
peah3f08dc62016-05-05 03:03:55 -0700184#endif
185 }
186
peah69221db2017-01-27 03:28:19 -0800187 void DumpRaw(const char* name, int32_t v) {
188#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200189 if (recording_activated_) {
190 FILE* file = GetRawFile(name);
191 fwrite(&v, sizeof(v), 1, file);
192 }
peah69221db2017-01-27 03:28:19 -0800193#endif
194 }
195
196 void DumpRaw(const char* name, size_t v_length, const int32_t* v) {
197#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200198 if (recording_activated_) {
199 FILE* file = GetRawFile(name);
200 fwrite(v, sizeof(v[0]), v_length, file);
201 }
peah69221db2017-01-27 03:28:19 -0800202#endif
203 }
204
205 void DumpRaw(const char* name, size_t v) {
206#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200207 if (recording_activated_) {
208 FILE* file = GetRawFile(name);
209 fwrite(&v, sizeof(v), 1, file);
210 }
peah69221db2017-01-27 03:28:19 -0800211#endif
212 }
213
214 void DumpRaw(const char* name, size_t v_length, const size_t* v) {
peahf28a3892016-09-01 08:58:21 -0700215#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200216 if (recording_activated_) {
217 FILE* file = GetRawFile(name);
218 fwrite(v, sizeof(v[0]), v_length, file);
219 }
peah3f08dc62016-05-05 03:03:55 -0700220#endif
221 }
222
223 void DumpRaw(const char* name, rtc::ArrayView<const int32_t> v) {
peahf28a3892016-09-01 08:58:21 -0700224#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200225 if (recording_activated_) {
226 DumpRaw(name, v.size(), v.data());
227 }
peah3f08dc62016-05-05 03:03:55 -0700228#endif
229 }
230
Jesús de Vicente Peña44974e12018-11-20 12:54:23 +0100231 void DumpRaw(const char* name, rtc::ArrayView<const size_t> v) {
232#if WEBRTC_APM_DEBUG_DUMP == 1
233 DumpRaw(name, v.size(), v.data());
234#endif
235 }
236
peahb46083e2016-05-03 07:01:18 -0700237 void DumpWav(const char* name,
peah69221db2017-01-27 03:28:19 -0800238 size_t v_length,
peahb46083e2016-05-03 07:01:18 -0700239 const float* v,
240 int sample_rate_hz,
241 int num_channels) {
peahf28a3892016-09-01 08:58:21 -0700242#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200243 if (recording_activated_) {
244 WavWriter* file = GetWavFile(name, sample_rate_hz, num_channels);
245 file->WriteSamples(v, v_length);
246 }
peahb46083e2016-05-03 07:01:18 -0700247#endif
248 }
249
peahca4cac72016-06-29 15:26:12 -0700250 void DumpWav(const char* name,
251 rtc::ArrayView<const float> v,
252 int sample_rate_hz,
253 int num_channels) {
peahf28a3892016-09-01 08:58:21 -0700254#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200255 if (recording_activated_) {
256 DumpWav(name, v.size(), v.data(), sample_rate_hz, num_channels);
257 }
peahca4cac72016-06-29 15:26:12 -0700258#endif
259 }
260
peahb46083e2016-05-03 07:01:18 -0700261 private:
peahf28a3892016-09-01 08:58:21 -0700262#if WEBRTC_APM_DEBUG_DUMP == 1
Per Åhgren7a95e0f2018-10-25 09:56:49 +0200263 static bool recording_activated_;
Alessio Bazzica4bc60452018-11-20 12:44:15 +0100264 static constexpr size_t kOutputDirMaxLength = 1024;
265 static char output_dir_[kOutputDirMaxLength];
peahb46083e2016-05-03 07:01:18 -0700266 const int instance_index_;
267 int recording_set_index_ = 0;
268 std::unordered_map<std::string, std::unique_ptr<FILE, RawFileCloseFunctor>>
269 raw_files_;
270 std::unordered_map<std::string, std::unique_ptr<WavWriter>> wav_files_;
271
272 FILE* GetRawFile(const char* name);
273 WavWriter* GetWavFile(const char* name, int sample_rate_hz, int num_channels);
274#endif
275 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ApmDataDumper);
276};
277
278} // namespace webrtc
279
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200280#endif // MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_