HART  0.2.0
High level Audio Regression and Testing
Loading...
Searching...
No Matches
hart_utils.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm> // min(), max()
4#include <cctype> // isalpha()
5#include <cmath> // pow()
6#include <limits> // infinity(), nan()
7#include <memory>
8#include <string>
9#include <unordered_map>
10
12
13namespace hart
14{
15
16/// @defgroup Utilities Utilities
17/// @brief Handy functions and constants
18/// @{
19
20/// @brief Infinity
21constexpr double inf = std::numeric_limits<double>::infinity();
22
23/// @brief Infinity
24constexpr double oo = inf;
25
26/// @brief pi
27constexpr double pi = 3.14159265358979323846;
28
29/// @brief 2 * pi
30constexpr double twoPi = 2.0 * pi;
31
32/// @brief pi / 2
33constexpr double halfPi = pi / 2.0;
34
35/// @brief Helper values for channel indices
37{
38 left = 0,
39 right = 1
40};
41
42/// @brief Helper values for mid-side channel indices
44{
45 mid = 0,
46 side = 1
47};
48
49/// @brief Helper values for something that could loop, like a Signal
50enum class Loop
51{
52 no,
53 yes
54};
55
56/// @brief Returns a quiet NaN value for the given floating-point type.
57template<typename FloatType>
58inline FloatType nan()
59{
60 return std::numeric_limits<FloatType>::quiet_NaN();
61}
62
63/// @brief `std::clamp()` replacement for C++11
64template <typename NumericType>
65NumericType clamp (const NumericType& value, const NumericType& low, const NumericType& high)
66{
67 return std::min<NumericType> (std::max<NumericType> (value, low), high);
68}
69
70/// @brief Converts dB to linear value (ratio)
71/// @param valueDb Value in decibels
72/// @return Value in linear domain
73template <typename SampleType>
74inline static SampleType decibelsToRatio (SampleType valueDb)
75{
76 if (valueDb < -120)
77 return 0;
78
79 return std::pow (static_cast<SampleType> (10), valueDb / static_cast<SampleType> (20));
80}
81
82/// @brief Converts linear value (ratio) to dB
83/// @param valueLinear Value in linear domain
84/// @return Value in decibels
85template <typename SampleType>
86inline static SampleType ratioToDecibels (SampleType valueLinear)
87{
88 if (valueLinear < 1e-6)
89 return -120;
90
91 return static_cast<SampleType> (20 * std::log10 (valueLinear));
92}
93
94/// @brief Compares two floating point numbers within a given tolerance
95template <typename SampleType>
96inline static SampleType floatsEqual (SampleType a, SampleType b, SampleType epsilon = (SampleType) 1e-8)
97{
98 return std::abs (a - b) < epsilon;
99}
100
101/// @brief Compares two floating point numbers within a given tolerance
102template <typename SampleType>
103inline static SampleType floatsNotEqual (SampleType a, SampleType b, SampleType epsilon = (SampleType) 1e-8)
104{
105 return std::abs (a - b) >= epsilon;
106}
107
108/// @brief Rounds a floating point value to a `size_t` value
109template <typename SampleType>
110inline static size_t roundToSizeT (SampleType x)
111{
112 return static_cast<size_t> (x + (SampleType) 0.5);
113}
114
115/// @brief Keeps phase in 0..twoPi range
116template <typename SampleType>
117SampleType wrapPhase (const SampleType phaseRadians)
118{
119 SampleType wrappedPhaseRadians = std::remainder (phaseRadians, (SampleType) hart::twoPi);
120
121 if (wrappedPhaseRadians < 0.0)
122 wrappedPhaseRadians += hart::twoPi;
123
124 return wrappedPhaseRadians;
125}
126
127/// @brief Checks if the provided file path is absolute
128inline static bool isAbsolutePath (const std::string& path)
129{
130 if (path.empty())
131 return false;
132
133 if (path[0] == '/' || path[0] == '\\')
134 return true;
135
136 #ifdef _WIN32
137 if (path.size() > 1 && std::isalpha (path[0]) && path[1] == ':')
138 return true;
139 #endif
140
141 return false;
142}
143
144/// @brief Converts path to absolute, if it's relative
145/// @details Relative paths are resolved based on a provided `--data-root-path` CLI argument
146inline static std::string toAbsolutePath (const std::string& path)
147{
148 if (isAbsolutePath(path))
149 return path;
150
152}
153
154/// @brief `std::unordered_map::contains()` replacement for C++11
155template <typename KeyType, typename ValueType>
156inline static bool contains (const std::unordered_map<KeyType, ValueType>& map, const KeyType& key)
157{
158 return map.find (key) != map.end();
159}
160
161/// @brief `std::make_unique()` replacement for C++11
162/// @details For C++11 compatibility only. If you're one C++14 or later, just use STL version.
163template<typename ObjectType, typename... Args>
164std::unique_ptr<ObjectType> make_unique (Args&&... args)
165{
166 return std::unique_ptr<ObjectType> (new ObjectType (std::forward<Args> (args)...));
167}
168
169/// @brief Defines a basic string representation of your class
170/// @details If your class takes ctor arguments, it's strongly encouraged to make a proper
171/// implementation of `represent()`, so that you get more detailed test failure reports.
172/// See @ref hart::DSP::represent(), @ref hart::Matcher::represent(),
173/// @ref hart::Signal::represent() for the description.
174#define HART_DEFINE_GENERIC_REPRESENT(ClassName)
175 virtual void represent(std::ostream& stream) const override
176 {
177 stream << #ClassName "()";
178 }
179
180/// @private
181#if defined(__GNUC__) || defined(__clang__)
182 #define HART_DEPRECATED(msg) __attribute__((deprecated(msg)))
183#elif defined(_MSC_VER)
184 #define HART_DEPRECATED(msg) __declspec(deprecated(msg))
185#else
186 #define HART_DEPRECATED(msg)
187#endif
188
189} // namespace hart
constexpr double twoPi
2 * pi
static bool isAbsolutePath(const std::string &path)
Checks if the provided file path is absolute.
FloatType nan()
Returns a quiet NaN value for the given floating-point type.
Channel
Helper values for channel indices.
SampleType wrapPhase(const SampleType phaseRadians)
Keeps phase in 0..twoPi range.
static bool contains(const std::unordered_map< KeyType, ValueType > &map, const KeyType &key)
std::unordered_map::contains() replacement for C++11
constexpr double halfPi
pi / 2
static size_t roundToSizeT(SampleType x)
Rounds a floating point value to a size_t value.
constexpr double inf
Infinity.
static SampleType ratioToDecibels(SampleType valueLinear)
Converts linear value (ratio) to dB.
static SampleType floatsNotEqual(SampleType a, SampleType b, SampleType epsilon=(SampleType) 1e-8)
Compares two floating point numbers within a given tolerance.
MidSideChannel
Helper values for mid-side channel indices.
std::unique_ptr< ObjectType > make_unique(Args &&... args)
std::make_unique() replacement for C++11
NumericType clamp(const NumericType &value, const NumericType &low, const NumericType &high)
std::clamp() replacement for C++11
constexpr double oo
Infinity.
static std::string toAbsolutePath(const std::string &path)
Converts path to absolute, if it's relative.
static SampleType decibelsToRatio(SampleType valueDb)
Converts dB to linear value (ratio)
constexpr double pi
pi
static SampleType floatsEqual(SampleType a, SampleType b, SampleType epsilon=(SampleType) 1e-8)
Compares two floating point numbers within a given tolerance.
Loop
Helper values for something that could loop, like a Signal.
Holds values set by the user via CLI interface.
std::string getDataRootPath()
Get data root path set by a "`--data-root-path`,`-d`" argument.
static CLIConfig & getInstance()
Get the singleton instance.