2 //used to create an out ugen automatically and a fade envelope
4 *wrapOut { arg name, func, rates, prependArgs, outClass=\Out, fadeTime;
5 ^SynthDef.new(name, { arg i_out=0;
7 result = SynthDef.wrap(func, rates, prependArgs).asUGenInput;
10 // Out, SendTrig etc. probably a 0.0
14 result = this.makeFadeEnv(fadeTime) * result;
16 outClass = outClass.asClass;
17 outClass.replaceZeroesWithSilence(result.asArray);
18 outClass.multiNewList([rate, i_out]++result)
23 *makeFadeEnv { arg fadeTime = (0.02);
24 var dt = NamedControl.kr(\fadeTime, fadeTime);
25 var gate = NamedControl.kr(\gate, 1.0);
26 var startVal = (dt <= 0);
29 ^EnvGen.kr(Env.new([startVal, 1, 0], #[1, 1], \lin, 1), gate, 1.0, 0.0, dt, 2)
40 *new { arg i_level=1, gate, fadeTime, doneAction=2, curve='sin';
41 var synthGate = gate ?? { NamedControl.kr(\gate, 1.0) };
42 var synthFadeTime = fadeTime ?? { NamedControl.kr(\fadeTime, 0.02) };
43 var startVal = (synthFadeTime <= 0);
45 Env.new([ startVal, 1.0, 0.0], #[1.0, 1.0], curve, 1),
46 synthGate, i_level, 0.0, synthFadeTime, doneAction
54 classvar currentControl, buildSynthDef;
57 *new { arg i_level=1, gate, fadeTime, doneAction=2, curve='sin';
58 var synthGate, synthFadeTime, startVal;
59 if(gate.isNil and: { fadeTime.isNil }) {
60 #synthGate, synthFadeTime = this.currentControl
62 synthGate = gate ?? { Control.names('gate').kr(1.0) }; synthFadeTime = fadeTime ?? { Control.names('fadeTime').kr(0.02) };
64 startVal = (synthFadeTime <= 0);
66 Env.new([ startVal,1,0], #[1,1],curve,1),
67 synthGate, i_level, 0.0, synthFadeTime, doneAction
71 // this allows several instances within a single synthdef
73 if(this.hasCurrentControl.not) {
74 currentControl = Control.names(['gate', 'fadeTime']).kr([1, 0.02]);
75 buildSynthDef = UGen.buildSynthDef;
80 ^UGen.buildSynthDef === buildSynthDef and: { currentControl.notNil }
87 classvar currentControls, buildSynthDef;
89 var <name, <values, <lags, <rate, <fixedLag;
92 *ar { arg name, values, lags;
93 ^this.new(name, values, \audio, lags, false)
96 *kr { arg name, values, lags, fixedLag = false;
97 ^this.new(name, values, \control, lags, fixedLag)
100 *ir { arg name, values, lags;
101 ^this.new(name, values, \scalar, lags, false)
104 *tr { arg name, values, lags;
105 ^this.new(name, values, \trigger, lags, false)
108 *new { arg name, values, rate, lags, fixedLag = false;
113 res = currentControls.at(name);
117 values = (values ? 0.0).asArray;
118 res = super.newCopyArgs(name, values, lags, rate, fixedLag).init;
119 currentControls.put(name, res);
121 values = (values ? res.values).asArray;
122 if(res.values != values) {
123 Error("NamedControl: cannot have more than one set of "
124 "default values in the same control.").throw;
126 if(rate.notNil and: { res.rate != rate }) {
127 Error("NamedControl: cannot have more than one set of "
128 "rates in the same control.").throw;
133 if(res.fixedLag and: lags.notNil) {
134 if( res.lags != lags ) {
135 Error("NamedControl: cannot have more than one set of "
136 "fixed lag values in the same control.").throw;
143 res.control.lag(lags.asArray)
150 var prefix, ctlName, ctl, selector;
153 name = name.asString;
154 if(name[1] == $_) { prefix = name[0]; ctlName = name[2..] } { ctlName = name };
157 if(fixedLag && lags.notNil && prefix.isNil) {
158 buildSynthDef.addKr(name, values.unbubble);
159 control = LagControl.kr(values.flat.unbubble, lags);
161 if(prefix == $a or: {rate === \audio}) {
162 buildSynthDef.addAr(name, values.unbubble);
163 control = AudioControl.ar(values.flat.unbubble);
166 if(prefix == $t or: {rate === \trigger}) {
167 buildSynthDef.addTr(name, values.unbubble);
168 control = TrigControl.kr(values.flat.unbubble);
170 if(prefix == $i or: {rate === \scalar}) {
171 buildSynthDef.addIr(name, values);
172 control = Control.ir(values.flat.unbubble);
174 buildSynthDef.addKr(name, values.unbubble);
175 control = Control.kr(values.flat.unbubble);
181 control = control.asArray.reshapeLike(values).unbubble;
185 if(UGen.buildSynthDef !== buildSynthDef or: currentControls.isNil) {
186 buildSynthDef = UGen.buildSynthDef;
187 currentControls = IdentityDictionary.new;