-
Notifications
You must be signed in to change notification settings - Fork 0
/
psSet-event-type.scd
145 lines (139 loc) · 4.92 KB
/
psSet-event-type.scd
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
Event.addEventType(\psSet, {
var value,
sustain = ~sustain.value,
releaseHolder = ~releaseHolder,
skipArgs = IdentitySet.with(\gate, \fadeTime, \out).addAll(~skipArgs);
var checkName;
if(~setArgs.notNil) {
checkName = { |cname| ~setArgs.includes(cname) }
} {
checkName = { |cname| skipArgs.includes(cname).not }
};
~freq = ~detunedFreq.value;
~amp = ~amp.value;
~proxyspace.keysValuesDo { |name, proxy|
var ctl = proxy.objects[0];
case // most specific cases (ScalarSynthControl) should come first
{ ctl.isKindOf(StreamControl) and: { ctl.source.isNumber } } {
if(checkName.(name.asSymbol) and: { (value = name.envirGet).notNil }) {
proxy.source = value;
if(name == \gt and: { sustain.notNil and: { sustain < inf } }) {
if(releaseHolder.notNil) {
releaseHolder[proxy] = thisThread.clock.beats + sustain;
};
thisThread.clock.sched(sustain, {
if(releaseHolder.isNil or: { releaseHolder[proxy] ? 0 <= thisThread.clock.beats }) {
proxy.source = 0;
};
});
};
};
}
{ ctl.isKindOf(SynthControl) } {
proxy.controlNames.do { |cn|
var cname = cn.name.asSymbol;
if(checkName.(cname) and: { // if... don't skip me
proxy.nodeMap[cname].isKindOf(BusPlug).not and: { // and I'm not mapped to a proxy
(value = cname.envirGet).notNil // and I have a value
}
}) {
// prevent infinite loops by not 'set'-ting to the same value
if(value != proxy.nodeMap[cname]) {
proxy.set(cn.name, value);
};
if(cn.name == \gt and: { sustain.notNil and: { sustain < inf } }) {
if(releaseHolder.notNil) {
releaseHolder[proxy] = thisThread.beats + sustain;
};
thisThread.clock.sched(sustain, {
if(releaseHolder.isNil or: { releaseHolder[proxy] ? 0 <= thisThread.beats }) {
proxy.set(cn.name, 0)
};
});
};
};
};
}
};
});
AbstractPlayControl.proxyControlClasses[\psSet] = PatternControl;
AbstractPlayControl.buildMethods[\psSet] = { |pattern, proxy, channelOffset = 0, index|
var watcher, rest = false;
if(currentEnvironment.isKindOf(ProxySpace).not) {
Error("\\psSet may not be used outside of a ProxySpace").throw;
};
// I don't have access to the stream player in here.
// To silence the proxy upon 'stop', I have to set a flag
// to turn events into rests.
// If rest is true, all events will be rests.
// Otherwise respect the existing isRest
watcher = SimpleController(proxy)
.put(\play, { rest = false })
.put(\stop, { rest = true })
.put(\clear, { rest = true; watcher.remove });
// releaseHolder may well be a hack,
// but it should actually be local to the pattern
// must protect in a Ref
// Pbindf will extract its value automatically
// but not use composeEvents()
Pbindf(pattern,
\type, \psSet,
\proxyspace, currentEnvironment,
\releaseHolder, `(IdentityDictionary.new),
#[gt, t_trig], Pfunc { |ev|
var gt = ev[\gt] ?? { 1 };
[
if(rest or: { ev.isRest ?? { false } })
{ Rest(gt) } { gt },
ev[\t_trig] ?? { 1 }
]
},
).buildForProxy(proxy, channelOffset, index)
};
StartUp.add {
// condition should be true in 3.6, false in 3.7
if(SynthDescLib.global['system_setbus_control_1'].isNil) {
(1 .. SystemSynthDefs.numChannels).do { arg i;
SynthDef("system_setbus_audio_" ++ i, { arg out = 0, fadeTime = 0, curve = 0, gate = 1;
var values = NamedControl.ir(\values, 0 ! i);
var env = Env([In.ar(out, i), values, values], [1, 0], curve, 1);
var sig = EnvGen.ar(env, gate + Impulse.kr(0), timeScale: fadeTime, doneAction: 2);
ReplaceOut.ar(out, sig);
}, [\ir, \kr, \ir, \kr]).add;
SynthDef("system_setbus_control_" ++ i, { arg out = 0, fadeTime = 0, curve = 0;
var values = NamedControl.ir(\values, 0 ! i);
var env = Env([In.kr(out, i), values], [1], curve);
var sig = EnvGen.kr(env, timeScale: fadeTime, doneAction: 2);
ReplaceOut.kr(out, sig);
}, [\ir, \kr, \ir]).add;
};
};
if(Event.default.eventTypes[\fadeBus].isNil) {
Event.addEventType(\fadeBus, #{ |server|
var bundle, instrument, rate, bus;
var array = ~array.as(Array);
var numChannels = min(~numChannels.value ? 1, array.size);
if(numChannels > SystemSynthDefs.numChannels) {
Error(
"Can't set more than % channels with current setup in SystemSynthDefs."
.format(SystemSynthDefs.numChannels)
).throw;
};
if (~id.isNil) {
~id = if(~rate == \audio) { server.nextNodeID } { -1 };
};
instrument = "system_setbus_%_%".format(~rate.value ? \control, numChannels);
// addToTail, so that old bus value can be overridden:
bundle = [9, instrument, ~id, 1, ~group.asControlInput,
"values", array,
"out", ~out.value,
"fadeTime", ~fadeTime,
"curve", ~curve
].asOSCArgArray;
~schedBundle.value(~lag, ~timingOffset, server, bundle);
if(~rate == \audio) { // control rate synth frees by itself, because bus holds the value
~stopServerNode = { server.sendBundle(server.latency, [\n_set, ~id, \gate, 0]) }
};
});
};
};