-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsynth_api.cpp
More file actions
194 lines (155 loc) · 4.74 KB
/
Copy pathsynth_api.cpp
File metadata and controls
194 lines (155 loc) · 4.74 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#include <cmath>
#include <fstream>
#include <random>
using namespace std;
#include "synth_api.h"
#include "pcm_wrapper.h"
#include "util.h"
namespace synth {
bool first;
int frame {0};
double bps {120};
double t {0};
double tq {0};
double f {0};
double w {0};
double nl {0};
double nlq {0};
double nt {0};
double ntq {0};
default_random_engine rng;
uniform_real_distribution<float> dist(-1, 1);
void incr_frame(const int bpm) {
++frame;
t = (double) frame / SAMPLE_FREQUENCY;
bps = (double) bpm / 60;
tq = t * bps;
}
void reset_frame() {
frame = -1;
t = 0;
tq = 0;
}
int frames_until(const evt_note &n) {
int note_start_frame = (SAMPLE_FREQUENCY * n.start) / 16 / bps;
if (frame < note_start_frame) {
return note_start_frame - frame;
}
int note_end_frame = (SAMPLE_FREQUENCY * (n.start + n.length)) / 16 / bps;
if (frame > note_end_frame) {
return note_end_frame - frame;
}
return 0;
}
int set_note(const evt_note &n) {
uint32_t note_start_frame = (SAMPLE_FREQUENCY * n.start) / 16 / bps;
if (frame < note_start_frame) {
return -1;
}
uint32_t note_end_frame = (SAMPLE_FREQUENCY * (n.start + n.length)) / 16 / bps;
if (frame > note_end_frame) {
return 1;
}
double note_progress = (double) (frame - note_start_frame) / (note_end_frame - note_start_frame);
double note_value = (double) n.start_note + (double) (n.end_note-n.start_note) * note_progress;
if (note_value < 1) note_value = 1;
f = 13.75 * pow(2, note_value / 12);
w = f * t * M_PI * 2;
nt = (double) (frame - note_start_frame) / SAMPLE_FREQUENCY;
ntq = nt * bps;
nlq = n.length / 16;
nl = nlq / bps;
return 0;
}
float sin(const float harmonic) {
return ::sin(harmonic * w);
}
float saw(const float harmonic) {
float x = harmonic * t * f / 2;
return 2 * (x - (int) x) - 1;
}
float sqr(const float harmonic) {
return sin(harmonic) > 0 ? 1 : -1;
}
float noise() {
return dist(rng);
}
float sin_t(const float multiplier) {
return ::sin(t * multiplier * M_PI * 2);
}
float sqr_t(const float multiplier) {
return sin(multiplier) > 0 ? 1 : -1;
}
float saw_t(const float multiplier) {
float x = t * multiplier / 2;
return 2 * (x - (int) x) - 1;
}
float sin_tq(const float multiplier) {
return ::sin(tq * multiplier * M_PI * 2);
}
float sqr_tq(const float multiplier) {
return sin_tq(multiplier) > 0 ? 1 : -1;
}
float saw_tq(const float multiplier) {
float x = tq * multiplier / 2;
return 2 * (x - (int) x) - 1;
}
float root(const float v) {
if (v == 0) return 0;
if (v < 0) return -root(-v);
const float xhalf = 0.5f * v;
union {
float x;
int i;
} u;
u.x = v;
u.i = 0x5f3759df - (u.i >> 1);
return v * u.x * (1.5f - xhalf * u.x * u.x);
}
float pow(const float v, const float p) {
return ::pow(v, p);
}
float min(const float a, const float b) {
return a < b ? a : b;
}
float max(const float a, const float b) {
return a > b ? a : b;
}
float env_t(const float attack, const float fade) {
float v = 1;
if (attack > 0 && nt < attack) {
v = nt / attack;
}
if (nt > nl - fade) {
float v2 = (nl - fade) / (nl - nt);
if (v2 < v) return v2;
}
return v;
}
float env_tq(const float attack, const float fade) {
float v = 1;
if (attack > 0 && ntq < attack) {
v = ntq / attack;
}
if (ntq > nlq - fade) {
float v2 = (nlq - fade) / (nlq - ntq);
if (v2 < v) return v2;
}
return v;
}
float mix(const float a, const float b, const float x) {
if (x <= 0) return a;
if (x >= 1) return b;
return a * (1.0 - x) + b * x;
}
float scale(const float lower_bound_from, const float upper_bound_from,
const float lower_bound_to, const float upper_bound_to,
const float value) {
return value * (upper_bound_to - lower_bound_to) / (upper_bound_from - lower_bound_from)
+ lower_bound_to - lower_bound_from;
}
float scale01(const float lower_bound_from, const float upper_bound_from,
const float value) {
return scale(lower_bound_from, upper_bound_from, 0, 1, value);
}
}