-
Notifications
You must be signed in to change notification settings - Fork 8
/
wave.h
97 lines (77 loc) · 1.63 KB
/
wave.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// wave.h // interpolated lookup table
#ifndef WAVE
#include <functional>
namespace soundmath
{
const int TABSIZE = 2048;
template <typename T> class Wave
{
public:
Wave() { }
~Wave() { }
Wave(std::function<T(T)> shape, T left = 0, T right = 1, bool periodic = true)
{
this->shape = shape;
this->left = left;
this->right = right;
this->periodic = periodic;
for (int i = 0; i < TABSIZE; i++)
{
T phase = (T) i / TABSIZE;
table[i] = shape((1 - phase) * left + phase * right);
}
this->endpoint = shape(right);
}
#ifdef FUNCTIONAL
T lookup(T input)
{
return shape(input);
}
#else
T lookup(T input)
{
T phase = (input - left) / (right - left);
// get value at endpoint if input is out of bounds
if (!periodic && (phase < 0 || phase >= 1))
{
if (phase < 0)
return none(0);
else
return endpoint;
}
else
{
phase += 1;
phase -= int(phase);
int center = (int)(phase * TABSIZE) % TABSIZE;
int after = (center + 1) % TABSIZE;
T disp = (phase * TABSIZE - center);
disp -= int(disp);
return linear(center, after, disp);
}
}
#endif
T operator()(T phase)
{
return lookup(phase);
}
protected:
T table[TABSIZE];
private:
T left; // input phases are interpreted as lying in [left, right)
T right;
bool periodic;
T endpoint; // if (this->periodic == false), provides a value for (*this)(right)
std::function<T(T)> shape;
T none(int center)
{
return table[center];
}
T linear(int center, int after, T disp)
{
return table[center] * (1 - disp) + table[after] * disp;
}
};
}
#define WAVE
#endif