-
Notifications
You must be signed in to change notification settings - Fork 0
/
RTSoundObject.pde
124 lines (99 loc) · 3.37 KB
/
RTSoundObject.pde
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
/** crude but good enough implementation of a SoundObject
* that supports amp attack-sustain-release envelope
* and frequency modulation
*/
static class RTSoundObject {
static boolean enabled = false;
Oscillator osc;
int playing = 0;
int osc_type;
float amp = 1.0;
float freq = 0.0;
float enved_amp = 0.0;
float modded_freq = 0.0;
static int amp_env_start_ticks = 1; // attack duration
static float amp_env_start_mod = 0.4; // attack strength
static float amp_env_mid_amp = 0.8; // sustain amplitude
static int amp_env_end_ticks = 1; // release duration
static float amp_env_end_mod = 0.05; // release strength
static float freq_mod_mod = 0.0; // modulation strength
static int freq_mod_startafter = 12; // modulation delay
static float freq_mod_limit = 8.0; // modulation bounds
int amp_env_start_curtick = 0;
int amp_env_end_curtick = 0;
int freq_mod_curtick = 0;
int freq_mod_curdir = 1;
RTSoundObject(Oscillator osc) {
this.osc = osc;
}
void tick() {
if (!RTSoundObject.enabled || playing == 0) return;
if (freq_mod_curtick >= RTSoundObject.freq_mod_startafter) {
modded_freq += RTSoundObject.freq_mod_mod * freq_mod_curdir;
if (modded_freq > freq + RTSoundObject.freq_mod_limit || modded_freq < freq - RTSoundObject.freq_mod_limit) freq_mod_curdir *= -1;
osc.freq(modded_freq);
}
if (playing == 1) {
if (amp_env_start_curtick <= RTSoundObject.amp_env_start_ticks) {
enved_amp += RTSoundObject.amp_env_start_mod;
amp_env_start_curtick++;
}
else if (enved_amp != RTSoundObject.amp_env_mid_amp) enved_amp = RTSoundObject.amp_env_mid_amp;
osc.amp(constrain(enved_amp, 0, 1) * amp);
}
else if (playing == -1) {
if (amp_env_end_curtick <= RTSoundObject.amp_env_end_ticks) {
enved_amp -= RTSoundObject.amp_env_end_mod;
amp_env_end_curtick++;
osc.amp(constrain(enved_amp, 0, 1) * amp);
}
else {
osc.stop();
playing = 0;
reset_mods_and_envs();
}
}
freq_mod_curtick++;
}
void freq(float f) {
this.freq = f;
this.modded_freq = f;
freq_mod_curdir = 1;
freq_mod_curtick = 0;
osc.freq(f);
}
void pan(float p) {
osc.pan(p);
}
void amp(float a) {
this.amp = a;
if (!RTSoundObject.enabled) osc.amp(a);
else this.enved_amp = a;
}
void reset_mods_and_envs() {
osc.freq(freq);
enved_amp = 0;
modded_freq = freq;
amp_env_start_curtick = 0;
amp_env_end_curtick = 0;
freq_mod_curdir = 1;
freq_mod_curtick = 0;
}
void play() {
reset_mods_and_envs();
if (!RTSoundObject.enabled) osc.amp(amp);
else osc.amp(0);
osc.play();
playing = 1;
}
void stop() {
stop(false);
}
void stop(boolean force) {
if (force || !RTSoundObject.enabled) {
osc.stop();
reset_mods_and_envs();
}
else playing = -1;
}
}