• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2018 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_AGC2_RNN_VAD_TEST_UTILS_H_
12 #define MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_TEST_UTILS_H_
13 
14 #include <algorithm>
15 #include <array>
16 #include <fstream>
17 #include <limits>
18 #include <memory>
19 #include <string>
20 #include <type_traits>
21 #include <utility>
22 #include <vector>
23 
24 #include "api/array_view.h"
25 #include "modules/audio_processing/agc2/rnn_vad/common.h"
26 #include "rtc_base/checks.h"
27 
28 namespace webrtc {
29 namespace rnn_vad {
30 namespace test {
31 
32 constexpr float kFloatMin = std::numeric_limits<float>::min();
33 
34 // Fails for every pair from two equally sized rtc::ArrayView<float> views such
35 // that the values in the pair do not match.
36 void ExpectEqualFloatArray(rtc::ArrayView<const float> expected,
37                            rtc::ArrayView<const float> computed);
38 
39 // Fails for every pair from two equally sized rtc::ArrayView<float> views such
40 // that their absolute error is above a given threshold.
41 void ExpectNearAbsolute(rtc::ArrayView<const float> expected,
42                         rtc::ArrayView<const float> computed,
43                         float tolerance);
44 
45 // Reader for binary files consisting of an arbitrary long sequence of elements
46 // having type T. It is possible to read and cast to another type D at once.
47 template <typename T, typename D = T>
48 class BinaryFileReader {
49  public:
50   explicit BinaryFileReader(const std::string& file_path, size_t chunk_size = 0)
51       : is_(file_path, std::ios::binary | std::ios::ate),
52         data_length_(is_.tellg() / sizeof(T)),
53         chunk_size_(chunk_size) {
54     RTC_CHECK(is_);
55     SeekBeginning();
56     buf_.resize(chunk_size_);
57   }
58   BinaryFileReader(const BinaryFileReader&) = delete;
59   BinaryFileReader& operator=(const BinaryFileReader&) = delete;
60   ~BinaryFileReader() = default;
data_length()61   size_t data_length() const { return data_length_; }
ReadValue(D * dst)62   bool ReadValue(D* dst) {
63     if (std::is_same<T, D>::value) {
64       is_.read(reinterpret_cast<char*>(dst), sizeof(T));
65     } else {
66       T v;
67       is_.read(reinterpret_cast<char*>(&v), sizeof(T));
68       *dst = static_cast<D>(v);
69     }
70     return is_.gcount() == sizeof(T);
71   }
72   // If |chunk_size| was specified in the ctor, it will check that the size of
73   // |dst| equals |chunk_size|.
ReadChunk(rtc::ArrayView<D> dst)74   bool ReadChunk(rtc::ArrayView<D> dst) {
75     RTC_DCHECK((chunk_size_ == 0) || (chunk_size_ == dst.size()));
76     const std::streamsize bytes_to_read = dst.size() * sizeof(T);
77     if (std::is_same<T, D>::value) {
78       is_.read(reinterpret_cast<char*>(dst.data()), bytes_to_read);
79     } else {
80       is_.read(reinterpret_cast<char*>(buf_.data()), bytes_to_read);
81       std::transform(buf_.begin(), buf_.end(), dst.begin(),
82                      [](const T& v) -> D { return static_cast<D>(v); });
83     }
84     return is_.gcount() == bytes_to_read;
85   }
SeekForward(size_t items)86   void SeekForward(size_t items) { is_.seekg(items * sizeof(T), is_.cur); }
SeekBeginning()87   void SeekBeginning() { is_.seekg(0, is_.beg); }
88 
89  private:
90   std::ifstream is_;
91   const size_t data_length_;
92   const size_t chunk_size_;
93   std::vector<T> buf_;
94 };
95 
96 // Writer for binary files.
97 template <typename T>
98 class BinaryFileWriter {
99  public:
BinaryFileWriter(const std::string & file_path)100   explicit BinaryFileWriter(const std::string& file_path)
101       : os_(file_path, std::ios::binary) {}
102   BinaryFileWriter(const BinaryFileWriter&) = delete;
103   BinaryFileWriter& operator=(const BinaryFileWriter&) = delete;
104   ~BinaryFileWriter() = default;
105   static_assert(std::is_arithmetic<T>::value, "");
WriteChunk(rtc::ArrayView<const T> value)106   void WriteChunk(rtc::ArrayView<const T> value) {
107     const std::streamsize bytes_to_write = value.size() * sizeof(T);
108     os_.write(reinterpret_cast<const char*>(value.data()), bytes_to_write);
109   }
110 
111  private:
112   std::ofstream os_;
113 };
114 
115 // Factories for resource file readers.
116 // The functions below return a pair where the first item is a reader unique
117 // pointer and the second the number of chunks that can be read from the file.
118 // Creates a reader for the PCM samples that casts from S16 to float and reads
119 // chunks with length |frame_length|.
120 std::pair<std::unique_ptr<BinaryFileReader<int16_t, float>>, const size_t>
121 CreatePcmSamplesReader(const size_t frame_length);
122 // Creates a reader for the pitch buffer content at 24 kHz.
123 std::pair<std::unique_ptr<BinaryFileReader<float>>, const size_t>
124 CreatePitchBuffer24kHzReader();
125 // Creates a reader for the the LP residual coefficients and the pitch period
126 // and gain values.
127 std::pair<std::unique_ptr<BinaryFileReader<float>>, const size_t>
128 CreateLpResidualAndPitchPeriodGainReader();
129 // Creates a reader for the VAD probabilities.
130 std::pair<std::unique_ptr<BinaryFileReader<float>>, const size_t>
131 CreateVadProbsReader();
132 
133 constexpr size_t kNumPitchBufAutoCorrCoeffs = 147;
134 constexpr size_t kNumPitchBufSquareEnergies = 385;
135 constexpr size_t kPitchTestDataSize =
136     kBufSize24kHz + kNumPitchBufSquareEnergies + kNumPitchBufAutoCorrCoeffs;
137 
138 // Class to retrieve a test pitch buffer content and the expected output for the
139 // analysis steps.
140 class PitchTestData {
141  public:
142   PitchTestData();
143   ~PitchTestData();
144   rtc::ArrayView<const float, kBufSize24kHz> GetPitchBufView() const;
145   rtc::ArrayView<const float, kNumPitchBufSquareEnergies>
146   GetPitchBufSquareEnergiesView() const;
147   rtc::ArrayView<const float, kNumPitchBufAutoCorrCoeffs>
148   GetPitchBufAutoCorrCoeffsView() const;
149 
150  private:
151   std::array<float, kPitchTestDataSize> test_data_;
152 };
153 
154 // Returns true if the given optimization is available.
155 bool IsOptimizationAvailable(Optimization optimization);
156 
157 }  // namespace test
158 }  // namespace rnn_vad
159 }  // namespace webrtc
160 
161 #endif  // MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_TEST_UTILS_H_
162