/
noise.hpp
120 lines (96 loc) · 2.28 KB
/
noise.hpp
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#pragma once
#include <random>
#include "base.hpp"
#include "filters/filter.hpp"
namespace bogaudio {
namespace dsp {
class Seeds {
private:
std::mt19937 _generator;
Seeds();
unsigned int _next();
public:
Seeds(const Seeds&) = delete;
void operator=(const Seeds&) = delete;
static Seeds& getInstance();
static unsigned int next();
};
struct NoiseGenerator : Generator {
std::minstd_rand _generator; // one of the faster options.
NoiseGenerator() : _generator(Seeds::next()) {}
};
struct WhiteNoiseGenerator : NoiseGenerator {
std::uniform_real_distribution<float> _uniform;
WhiteNoiseGenerator() : _uniform(-1.0, 1.0) {}
float _next() override {
return _uniform(_generator);
}
};
template<typename G>
struct BasePinkNoiseGenerator : NoiseGenerator {
static const int _n = 7;
G _g;
G _gs[_n];
uint32_t _count = _g.next();
float _next() override {
// See: http://www.firstpr.com.au/dsp/pink-noise/
float sum = _g.next();
for (int i = 0, bit = 1; i < _n; ++i, bit <<= 1) {
if (_count & bit) {
sum += _gs[i].next();
}
else {
sum += _gs[i].current();
}
}
++_count;
return sum / (float)(_n + 1);
}
};
struct PinkNoiseGenerator : BasePinkNoiseGenerator<WhiteNoiseGenerator> {};
struct RedNoiseGenerator : BasePinkNoiseGenerator<PinkNoiseGenerator> {};
struct BlueNoiseGenerator : NoiseGenerator {
PinkNoiseGenerator _pink;
float _last = 0.0f;
float _next() override {
float t = _last;
_last = _pink.next();
return _last - t;
}
};
struct GaussianNoiseGenerator : NoiseGenerator {
std::normal_distribution<float> _normal;
GaussianNoiseGenerator(float mean = 0.0f, float stdDev = 1.0f) : _normal(mean, stdDev) {}
float _next() override {
return _normal(_generator);
}
};
struct RandomWalk : Generator {
float _min;
float _max;
float _last = 0.0f;
float _lastOut = 0.0f;
float _damp;
float _bias = 0.0f;
float _biasDamp = 1.0f;
WhiteNoiseGenerator _noise;
LowPassFilter _filter;
RandomWalk(
float min = -5.0f,
float max = 5.0f,
float sampleRate = 1000.0f,
float change = 0.5f
)
: _min(min)
, _max(max)
{
assert(_min < _max);
setParams(sampleRate, change);
}
void setParams(float sampleRate = 1000.0f, float change = 0.5f);
void jump();
void tell(float v);
float _next() override;
};
} // namespace dsp
} // namespace bogaudio