tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

apm_data_dumper.h (12433B)


      1 /*
      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 
     11 #ifndef MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_
     12 #define MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_
     13 
     14 #include <cstdint>
     15 #include <cstdio>
     16 #if WEBRTC_APM_DEBUG_DUMP == 1
     17 #include <memory>
     18 #include <string>
     19 #include <unordered_map>
     20 #endif
     21 
     22 #include "absl/strings/string_view.h"
     23 #include "api/array_view.h"
     24 #if WEBRTC_APM_DEBUG_DUMP == 1
     25 #include "common_audio/wav_file.h"
     26 #include "rtc_base/checks.h"
     27 #include "rtc_base/string_utils.h"
     28 #endif
     29 
     30 // Check to verify that the define is properly set.
     31 #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"
     34 #endif
     35 
     36 namespace webrtc {
     37 
     38 #if WEBRTC_APM_DEBUG_DUMP == 1
     39 // Functor used to use as a custom deleter in the map of file pointers to raw
     40 // files.
     41 struct RawFileCloseFunctor {
     42  void operator()(FILE* f) const { fclose(f); }
     43 };
     44 #endif
     45 
     46 // Class that handles dumping of variables into files.
     47 class ApmDataDumper {
     48 public:
     49  // 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() = delete;
     55  ApmDataDumper(const ApmDataDumper&) = delete;
     56  ApmDataDumper& operator=(const ApmDataDumper&) = delete;
     57 
     58  ~ApmDataDumper();
     59 
     60  // Activates or deactivate the dumping functionality.
     61  static void SetActivated([[maybe_unused]] bool activated) {
     62 #if WEBRTC_APM_DEBUG_DUMP == 1
     63    recording_activated_ = activated;
     64 #endif
     65  }
     66 
     67  // Returns whether dumping functionality is enabled/available.
     68  static bool IsAvailable() {
     69 #if WEBRTC_APM_DEBUG_DUMP == 1
     70    return true;
     71 #else
     72    return false;
     73 #endif
     74  }
     75 
     76  // Default dump set.
     77  static constexpr size_t kDefaultDumpSet = 0;
     78 
     79  // Specifies what dump set to use. All dump commands with a different dump set
     80  // than the one specified will be discarded. If not specificed, all dump sets
     81  // will be used.
     82  static void SetDumpSetToUse([[maybe_unused]] int dump_set_to_use) {
     83 #if WEBRTC_APM_DEBUG_DUMP == 1
     84    dump_set_to_use_ = dump_set_to_use;
     85 #endif
     86  }
     87 
     88  // Set an optional output directory.
     89  static void SetOutputDirectory(
     90      [[maybe_unused]] absl::string_view output_dir) {
     91 #if WEBRTC_APM_DEBUG_DUMP == 1
     92    RTC_CHECK_LT(output_dir.size(), kOutputDirMaxLength);
     93    strcpyn(output_dir_, kOutputDirMaxLength, output_dir);
     94 #endif
     95  }
     96 
     97  // Reinitializes the data dumping such that new versions
     98  // of all files being dumped to are created.
     99  void InitiateNewSetOfRecordings() {
    100 #if WEBRTC_APM_DEBUG_DUMP == 1
    101    ++recording_set_index_;
    102 #endif
    103  }
    104 
    105  // Methods for performing dumping of data of various types into
    106  // various formats.
    107  void DumpRaw([[maybe_unused]] absl::string_view name,
    108               [[maybe_unused]] double v,
    109               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    110 #if WEBRTC_APM_DEBUG_DUMP == 1
    111    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    112      return;
    113 
    114    if (recording_activated_) {
    115      FILE* file = GetRawFile(name);
    116      fwrite(&v, sizeof(v), 1, file);
    117    }
    118 #endif
    119  }
    120 
    121  void DumpRaw([[maybe_unused]] absl::string_view name,
    122               [[maybe_unused]] size_t v_length,
    123               [[maybe_unused]] const double* v,
    124               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    125 #if WEBRTC_APM_DEBUG_DUMP == 1
    126    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    127      return;
    128 
    129    if (recording_activated_) {
    130      FILE* file = GetRawFile(name);
    131      fwrite(v, sizeof(v[0]), v_length, file);
    132    }
    133 #endif
    134  }
    135 
    136  void DumpRaw([[maybe_unused]] absl::string_view name,
    137               [[maybe_unused]] ArrayView<const double> v,
    138               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    139 #if WEBRTC_APM_DEBUG_DUMP == 1
    140    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    141      return;
    142 
    143    if (recording_activated_) {
    144      DumpRaw(name, v.size(), v.data());
    145    }
    146 #endif
    147  }
    148 
    149  void DumpRaw([[maybe_unused]] absl::string_view name,
    150               [[maybe_unused]] float v,
    151               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    152 #if WEBRTC_APM_DEBUG_DUMP == 1
    153    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    154      return;
    155 
    156    if (recording_activated_) {
    157      FILE* file = GetRawFile(name);
    158      fwrite(&v, sizeof(v), 1, file);
    159    }
    160 #endif
    161  }
    162 
    163  void DumpRaw([[maybe_unused]] absl::string_view name,
    164               [[maybe_unused]] size_t v_length,
    165               [[maybe_unused]] const float* v,
    166               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    167 #if WEBRTC_APM_DEBUG_DUMP == 1
    168    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    169      return;
    170 
    171    if (recording_activated_) {
    172      FILE* file = GetRawFile(name);
    173      fwrite(v, sizeof(v[0]), v_length, file);
    174    }
    175 #endif
    176  }
    177 
    178  void DumpRaw([[maybe_unused]] absl::string_view name,
    179               [[maybe_unused]] ArrayView<const float> v,
    180               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    181 #if WEBRTC_APM_DEBUG_DUMP == 1
    182    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    183      return;
    184 
    185    if (recording_activated_) {
    186      DumpRaw(name, v.size(), v.data());
    187    }
    188 #endif
    189  }
    190 
    191  void DumpRaw([[maybe_unused]] absl::string_view name,
    192               [[maybe_unused]] bool v,
    193               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    194 #if WEBRTC_APM_DEBUG_DUMP == 1
    195    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    196      return;
    197 
    198    if (recording_activated_) {
    199      DumpRaw(name, static_cast<int16_t>(v));
    200    }
    201 #endif
    202  }
    203 
    204  void DumpRaw([[maybe_unused]] absl::string_view name,
    205               [[maybe_unused]] size_t v_length,
    206               [[maybe_unused]] const bool* v,
    207               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    208 #if WEBRTC_APM_DEBUG_DUMP == 1
    209    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    210      return;
    211 
    212    if (recording_activated_) {
    213      FILE* file = GetRawFile(name);
    214      for (size_t k = 0; k < v_length; ++k) {
    215        int16_t value = static_cast<int16_t>(v[k]);
    216        fwrite(&value, sizeof(value), 1, file);
    217      }
    218    }
    219 #endif
    220  }
    221 
    222  void DumpRaw([[maybe_unused]] absl::string_view name,
    223               [[maybe_unused]] ArrayView<const bool> v,
    224               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    225 #if WEBRTC_APM_DEBUG_DUMP == 1
    226    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    227      return;
    228 
    229    if (recording_activated_) {
    230      DumpRaw(name, v.size(), v.data());
    231    }
    232 #endif
    233  }
    234 
    235  void DumpRaw([[maybe_unused]] absl::string_view name,
    236               [[maybe_unused]] int16_t v,
    237               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    238 #if WEBRTC_APM_DEBUG_DUMP == 1
    239    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    240      return;
    241 
    242    if (recording_activated_) {
    243      FILE* file = GetRawFile(name);
    244      fwrite(&v, sizeof(v), 1, file);
    245    }
    246 #endif
    247  }
    248 
    249  void DumpRaw([[maybe_unused]] absl::string_view name,
    250               [[maybe_unused]] size_t v_length,
    251               [[maybe_unused]] const int16_t* v,
    252               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    253 #if WEBRTC_APM_DEBUG_DUMP == 1
    254    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    255      return;
    256 
    257    if (recording_activated_) {
    258      FILE* file = GetRawFile(name);
    259      fwrite(v, sizeof(v[0]), v_length, file);
    260    }
    261 #endif
    262  }
    263 
    264  void DumpRaw([[maybe_unused]] absl::string_view name,
    265               [[maybe_unused]] ArrayView<const int16_t> v,
    266               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    267 #if WEBRTC_APM_DEBUG_DUMP == 1
    268    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    269      return;
    270 
    271    if (recording_activated_) {
    272      DumpRaw(name, v.size(), v.data());
    273    }
    274 #endif
    275  }
    276 
    277  void DumpRaw([[maybe_unused]] absl::string_view name,
    278               [[maybe_unused]] int32_t v,
    279               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    280 #if WEBRTC_APM_DEBUG_DUMP == 1
    281    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    282      return;
    283 
    284    if (recording_activated_) {
    285      FILE* file = GetRawFile(name);
    286      fwrite(&v, sizeof(v), 1, file);
    287    }
    288 #endif
    289  }
    290 
    291  void DumpRaw([[maybe_unused]] absl::string_view name,
    292               [[maybe_unused]] size_t v_length,
    293               [[maybe_unused]] const int32_t* v,
    294               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    295 #if WEBRTC_APM_DEBUG_DUMP == 1
    296    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    297      return;
    298 
    299    if (recording_activated_) {
    300      FILE* file = GetRawFile(name);
    301      fwrite(v, sizeof(v[0]), v_length, file);
    302    }
    303 #endif
    304  }
    305 
    306  void DumpRaw([[maybe_unused]] absl::string_view name,
    307               [[maybe_unused]] size_t v,
    308               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    309 #if WEBRTC_APM_DEBUG_DUMP == 1
    310    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    311      return;
    312 
    313    if (recording_activated_) {
    314      FILE* file = GetRawFile(name);
    315      fwrite(&v, sizeof(v), 1, file);
    316    }
    317 #endif
    318  }
    319 
    320  void DumpRaw([[maybe_unused]] absl::string_view name,
    321               [[maybe_unused]] size_t v_length,
    322               [[maybe_unused]] const size_t* v,
    323               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    324 #if WEBRTC_APM_DEBUG_DUMP == 1
    325    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    326      return;
    327 
    328    if (recording_activated_) {
    329      FILE* file = GetRawFile(name);
    330      fwrite(v, sizeof(v[0]), v_length, file);
    331    }
    332 #endif
    333  }
    334 
    335  void DumpRaw([[maybe_unused]] absl::string_view name,
    336               [[maybe_unused]] ArrayView<const int32_t> v,
    337               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    338 #if WEBRTC_APM_DEBUG_DUMP == 1
    339    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    340      return;
    341 
    342    if (recording_activated_) {
    343      DumpRaw(name, v.size(), v.data());
    344    }
    345 #endif
    346  }
    347 
    348  void DumpRaw(absl::string_view name,
    349               ArrayView<const size_t> v,
    350               int dump_set = kDefaultDumpSet) {
    351 #if WEBRTC_APM_DEBUG_DUMP == 1
    352    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    353      return;
    354 
    355    DumpRaw(name, v.size(), v.data());
    356 #endif
    357  }
    358 
    359  void DumpWav([[maybe_unused]] absl::string_view name,
    360               [[maybe_unused]] size_t v_length,
    361               [[maybe_unused]] const float* v,
    362               [[maybe_unused]] int sample_rate_hz,
    363               [[maybe_unused]] int num_channels,
    364               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    365 #if WEBRTC_APM_DEBUG_DUMP == 1
    366    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    367      return;
    368 
    369    if (recording_activated_) {
    370      WavWriter* file = GetWavFile(name, sample_rate_hz, num_channels,
    371                                   WavFile::SampleFormat::kFloat);
    372      file->WriteSamples(v, v_length);
    373    }
    374 #endif
    375  }
    376 
    377  void DumpWav([[maybe_unused]] absl::string_view name,
    378               [[maybe_unused]] ArrayView<const float> v,
    379               [[maybe_unused]] int sample_rate_hz,
    380               [[maybe_unused]] int num_channels,
    381               [[maybe_unused]] int dump_set = kDefaultDumpSet) {
    382 #if WEBRTC_APM_DEBUG_DUMP == 1
    383    if (dump_set_to_use_ && *dump_set_to_use_ != dump_set)
    384      return;
    385 
    386    if (recording_activated_) {
    387      DumpWav(name, v.size(), v.data(), sample_rate_hz, num_channels);
    388    }
    389 #endif
    390  }
    391 
    392 private:
    393 #if WEBRTC_APM_DEBUG_DUMP == 1
    394  static bool recording_activated_;
    395  static std::optional<int> dump_set_to_use_;
    396  static constexpr size_t kOutputDirMaxLength = 1024;
    397  static char output_dir_[kOutputDirMaxLength];
    398  const int instance_index_;
    399  int recording_set_index_ = 0;
    400  std::unordered_map<std::string, std::unique_ptr<FILE, RawFileCloseFunctor>>
    401      raw_files_;
    402  std::unordered_map<std::string, std::unique_ptr<WavWriter>> wav_files_;
    403 
    404  FILE* GetRawFile(absl::string_view name);
    405  WavWriter* GetWavFile(absl::string_view name,
    406                        int sample_rate_hz,
    407                        int num_channels,
    408                        WavFile::SampleFormat format);
    409 #endif
    410 };
    411 
    412 }  // namespace webrtc
    413 
    414 #endif  // MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_