HART  0.2.0
High level Audio Regression and Testing
Loading...
Searching...
No Matches
hart_slice.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <utility>
4#include <algorithm>
5
7#include "hart_utils.hpp" // inf, floatsEqual()
8
9namespace hart
10{
11
12/// @brief Represents a slice of analysis data
13/// @details
14/// Slice stores the user's intent in a raw, domain-specific form.
15/// Interpretation happens later inside of containers like AudioBuffer or Spectrum.
16///
17/// Examples:
18/// @code
19/// Slice::frames (100, 200)
20/// Slice::time (50_ms, 100_ms)
21/// Slice::frequency (500_Hz, 1000_Hz)
22/// Slice::bins (10, 20)
23/// @endcode
24/// @ingroup DataStructures
25struct Slice
26{
27 enum class Type
28 {
29 whole,
30 frames,
31 time,
32 bins,
34 };
35
37 double start = -hart::inf;
38 double stop = hart::inf;
39
40 bool isEmpty () const
41 {
42 // TODO: Implement unit (type) aware tolerance
43
45 }
46
47 static Slice whole()
48 {
49 return Slice();
50 }
51
52 static Slice frames (size_t startFrame, size_t stopFrame)
53 {
54 if (startFrame > stopFrame)
55 HART_THROW_OR_RETURN (hart::SizeError, "Requested start is greater than its stop", whole());
56
57 Slice slice;
58 slice.type = Type::frames;
59 slice.start = static_cast<double> (startFrame);
60 slice.stop = static_cast<double> (stopFrame);
61 return slice;
62 }
63
64 static Slice time (double startSeconds, double stopSeconds)
65 {
66 // If a legitimate case for negative time boundary
67 // reveals itself, we can remove this check
68 if (startSeconds < 0.0 || stopSeconds < 0.0)
69 HART_THROW_OR_RETURN (hart::ValueError, "Slice boundaries should not be negative", whole());
70
71 if (startSeconds > stopSeconds)
72 HART_THROW_OR_RETURN (hart::SizeError, "Requested start is greater than its stop", whole());
73
74 Slice slice;
75 slice.type = Type::time;
76 slice.start = startSeconds;
77 slice.stop = stopSeconds;
78 return slice;
79 }
80
81 static Slice bins (size_t startBin, size_t stopBin)
82 {
83 if (startBin > stopBin)
84 HART_THROW_OR_RETURN (hart::SizeError, "Requested start is greater than its stop", whole());
85
86 Slice slice;
87 slice.type = Type::bins;
88 slice.start = static_cast<double> (startBin);
89 slice.stop = static_cast<double> (stopBin);
90 return slice;
91 }
92
93 static Slice freq (double startHz, double stopHz)
94 {
95 if (startHz < 0.0 || stopHz < 0.0)
96 HART_THROW_OR_RETURN (hart::ValueError, "Slice boundaries should not be negative", whole());
97
98 if (startHz > stopHz)
99 HART_THROW_OR_RETURN (hart::SizeError, "Requested start is greater than its stop", whole());
100
101 Slice slice;
102 slice.type = Type::frequency;
103 slice.start = startHz;
104 slice.stop = stopHz;
105 return slice;
106 }
107
108private:
109 Slice() = default;
110};
111
112} // namespace hart
Thrown when an unexpected container size is encountered.
Thrown when an inappropriate value is encountered.
#define HART_THROW_OR_RETURN(ExceptionType, message, returnValue)
Throws an exception if HART_DO_NOT_THROW_EXCEPTIONS is set, prints a message and returns a specified ...
constexpr double inf
Infinity.
static SampleType floatsEqual(SampleType a, SampleType b, SampleType epsilon=(SampleType) 1e-8)
Compares two floating point numbers within a given tolerance.
Represents a slice of analysis data.
static Slice freq(double startHz, double stopHz)
static Slice bins(size_t startBin, size_t stopBin)
static Slice time(double startSeconds, double stopSeconds)
static Slice frames(size_t startFrame, size_t stopFrame)
static Slice whole()
bool isEmpty() const