As an exercise, and also to illustrate some points about efficient SynthDef writing, here is a revision to Maths2 that also fixes the bug about scalar `linExp`

values.

Edit: I’m being picky about it for a couple of reasons – mainly to demonstrate some things that we *can* think about while writing synths. Sam explained later that this was written very quickly on low battery without access to power, so it wasn’t finished. That’s fine! I hope it’s helpful that I went ahead with some updates.

The main points:

- Multiplication is faster than division: so,
`x * SampleDur.ir`

is more efficient than`x / SampleRate.ir`

. - SC does
*not*automatically fold duplicate UGens down into one. If you write`SampleDur.ir`

10 times, there will be 10 instances of SampleDur.- This is even more important for operators. If you write
`linExp > 0.5`

six times, it will actually do the identical comparison operation six times. It’s much more efficient to save the result in a variable and reuse the variable in multiple places.

- This is even more important for operators. If you write
- The linear interpolation formula
`(y - x) * interp + x`

has one fewer multiplication than`(y * interp) + (x * (1 - interp))`

.- In general, it’s worth looking for algebraic reductions: e.g.,
`x.neg > 0`

is the same as`x < 0`

, except that the latter renders into a single UGen where the former requires two.

- In general, it’s worth looking for algebraic reductions: e.g.,

```
Maths2 {
*ar { |rise = 0.1, fall = 0.1, linExp = 0.5, loop = 1, plugged = 0, trig = 0|
var freq = (rise.clip(0.001, 10*60) + fall.clip(0.001, 10*60)).reciprocal;
var width = rise.clip(0.001, 10*60) / (rise.clip(0.001, 10*60) + fall.clip(0.001, 10*60));
// avoid multiple instances of the same UGen,
// if it's known that they're all the same.
// also dividing by SampleRate is slower than multiplying by SampleDur
var sampleDur = SampleDur.ir;
var plugTrig = Trig1.ar(1 - plugged, sampleDur);
var loopTrig = Trig1.ar(loop, sampleDur);
var eof, eor;
var maths, maths2, interp, isExp;
var phasor = Phasor.ar(Silent.ar + loopTrig + plugTrig, 2 * freq * sampleDur, -1, 1, -1);
var phasorTrig, latchTrig, postEnv;
var inTrig, phasor2, postEnv2;
var pluggedIsVariable = plugged.rate != \scalar;
var needMaths = pluggedIsVariable or: { plugged < 1 };
var needMaths2 = pluggedIsVariable or: { plugged >= 1 };
if(needMaths) {
phasorTrig = Trig1.ar(0.5 - phasor, sampleDur) + EnvGen.ar(Env([0, 0, 1, 0], [sampleDur, sampleDur, sampleDur]));
latchTrig = (phasorTrig + (DelayN.ar(loopTrig, 0.01, 0.01))).clip(0, 1);
postEnv = (Latch.ar(K2A.ar(loop), latchTrig) > 0);
phasor = phasor.linlin(-1, 1, width.neg, 1-width);
maths = phasor.bilin(0, width.neg, 1-width, 0, -1, 1);
maths = 1 - maths.abs;
maths = maths * postEnv;
};
if(needMaths2) {
inTrig = Trig1.ar(trig, sampleDur);
phasor2 = Phasor.ar(inTrig, 2 * freq * sampleDur, -1, 1, -1);
postEnv2 = SetResetFF.ar(Delay1.ar(inTrig), Trig1.ar(0.5 - phasor2, sampleDur));
phasor2 = phasor2.linlin(-1, 1, width.neg, 1 - width);
maths2 = phasor2.bilin(0, width.neg, 1 - width, 0, -1, 1);
maths2 = 1 - maths2.abs;
maths2 = maths2 * postEnv2;
};
if(pluggedIsVariable) {
maths = Select.ar(plugged, [maths, maths2]);
} {
if(plugged >= 1) { maths = maths2 };
};
isExp = linExp > 0.5; // don't repeat this 3 times
// could reduce here as well, if linExp is scalar
// but I'm tired now ;-p and these aren't expensive
interp = Select.kr(isExp, [linExp.linlin(0, 0.5, 1, 0), linExp.linlin(0.5, 1, 0, 1)]);
maths = Select.ar(isExp, [maths - 1, maths]);
// maths = (maths ** 8 * interp) + (maths * (1 - interp));
// - * + is more efficient than *, - * +
maths = ((maths ** 8) - maths) * interp + maths;
maths = Select.ar(isExp, [maths + 1, maths]);
if(pluggedIsVariable) {
// again, repeated multiplications...
postEnv = phasor * postEnv;
postEnv2 = phasor2 * postEnv2;
// x.neg > 0, same as x < 0, save one unary op
eof = Select.ar(plugged, [postEnv < 0, postEnv2 < 0]);
eor = Select.ar(plugged, [postEnv > 0, postEnv2 > 0]);
} {
if(plugged < 1) {
postEnv = phasor * postEnv;
eof = postEnv < 0;
eor = postEnv > 0;
} {
postEnv2 = phasor2 * postEnv2;
eof = postEnv2 < 0;
eor = postEnv2 > 0;
};
};
^[maths, eof, eor]
}
}
```

hjh