1 SimpleNumber : Number {
3 *new { ^this.shouldNotImplement(thisMethod) }
5 isValidUGenInput { ^this.isNaN.not }
8 magnitude { ^this.abs }
9 angle { if (this >= 0, {^0.0}, {^pi} ) }
12 neg { _Neg; ^this.primitiveFailed }
13 bitNot { _BitNot; ^this.primitiveFailed }
14 abs { _Abs; ^this.primitiveFailed }
15 ceil { _Ceil; ^this.primitiveFailed }
16 floor { _Floor; ^this.primitiveFailed }
17 frac { _Frac; ^this.primitiveFailed }
18 sign { _Sign; ^this.primitiveFailed }
19 squared { _Squared; ^this.primitiveFailed }
20 cubed { _Cubed; ^this.primitiveFailed }
21 sqrt { _Sqrt; ^this.primitiveFailed }
22 exp { _Exp; ^this.primitiveFailed }
23 reciprocal { _Recip; ^this.primitiveFailed }
24 midicps { _MIDICPS; ^this.primitiveFailed }
25 cpsmidi { _CPSMIDI; ^this.primitiveFailed }
26 midiratio { _MIDIRatio; ^this.primitiveFailed }
27 ratiomidi { _RatioMIDI; ^this.primitiveFailed }
28 ampdb { _AmpDb; ^this.primitiveFailed }
29 dbamp { _DbAmp; ^this.primitiveFailed }
30 octcps { _OctCPS; ^this.primitiveFailed }
31 cpsoct { _CPSOct; ^this.primitiveFailed }
32 log { _Log; ^this.primitiveFailed }
33 log2 { _Log2; ^this.primitiveFailed }
34 log10 { _Log10; ^this.primitiveFailed }
35 sin { _Sin; ^this.primitiveFailed }
36 cos { _Cos; ^this.primitiveFailed }
37 tan { _Tan; ^this.primitiveFailed }
38 asin { _ArcSin; ^this.primitiveFailed }
39 acos { _ArcCos; ^this.primitiveFailed }
40 atan { _ArcTan; ^this.primitiveFailed }
41 sinh { _SinH; ^this.primitiveFailed }
42 cosh { _CosH; ^this.primitiveFailed }
43 tanh { _TanH; ^this.primitiveFailed }
44 rand { _Rand; ^this.primitiveFailed }
45 rand2 { _Rand2; ^this.primitiveFailed }
46 linrand { _LinRand; ^this.primitiveFailed }
47 bilinrand { _BiLinRand; ^this.primitiveFailed }
48 sum3rand { _Sum3Rand; ^this.primitiveFailed }
50 distort { _Distort; ^this.primitiveFailed }
51 softclip { _SoftClip; ^this.primitiveFailed }
52 coin { _Coin; ^this.primitiveFailed }
53 isPositive { ^this >= 0 }
54 isNegative { ^this < 0 }
55 isStrictlyPositive { ^this > 0 }
56 isNaN { ^(this >= 0 or: { this <= 0 }).not }
57 asBoolean { ^this > 0 }
58 booleanValue { ^this > 0 } // TODO in the long-run, deprecate for asBoolean
59 binaryValue { ^this.sign.max(0) } // TODO in the long-run, deprecate for asInteger
61 rectWindow { _RectWindow; ^this.primitiveFailed }
62 hanWindow { _HanWindow; ^this.primitiveFailed }
63 welWindow { _WelchWindow; ^this.primitiveFailed }
64 triWindow { _TriWindow; ^this.primitiveFailed }
66 scurve { _SCurve; ^this.primitiveFailed }
67 ramp { _Ramp; ^this.primitiveFailed }
69 + { arg aNumber, adverb; _Add; ^aNumber.performBinaryOpOnSimpleNumber('+', this, adverb) }
70 - { arg aNumber, adverb; _Sub; ^aNumber.performBinaryOpOnSimpleNumber('-', this, adverb) }
71 * { arg aNumber, adverb; _Mul; ^aNumber.performBinaryOpOnSimpleNumber('*', this, adverb) }
72 / { arg aNumber, adverb; _FDiv; ^aNumber.performBinaryOpOnSimpleNumber('/', this, adverb) }
73 mod { arg aNumber, adverb; _Mod; ^aNumber.performBinaryOpOnSimpleNumber('mod', this, adverb) }
74 div { arg aNumber, adverb; _IDiv; ^aNumber.performBinaryOpOnSimpleNumber('div', this, adverb) }
75 pow { arg aNumber, adverb; _Pow; ^aNumber.performBinaryOpOnSimpleNumber('pow', this, adverb) }
76 min { arg aNumber, adverb; _Min; ^aNumber.performBinaryOpOnSimpleNumber('min', this, adverb) }
77 max { arg aNumber=0.0, adverb; _Max; ^aNumber.performBinaryOpOnSimpleNumber('max', this, adverb) }
78 bitAnd { arg aNumber, adverb; _BitAnd; ^aNumber.performBinaryOpOnSimpleNumber('bitAnd', this, adverb) }
79 bitOr { arg aNumber, adverb; _BitOr; ^aNumber.performBinaryOpOnSimpleNumber('bitOr', this, adverb) }
80 bitXor { arg aNumber, adverb; _BitXor; ^aNumber.performBinaryOpOnSimpleNumber('bitXor', this, adverb) }
81 bitHammingDistance { arg aNumber, adverb; _HammingDistance ^aNumber.performBinaryOpOnSimpleNumber('hammingDistance', this, adverb) }
82 bitTest { arg bit; ^( (this & 1.leftShift(bit)) != 0) }
83 lcm { arg aNumber, adverb; _LCM; ^aNumber.performBinaryOpOnSimpleNumber('lcm', this, adverb) }
84 gcd { arg aNumber, adverb; _GCD; ^aNumber.performBinaryOpOnSimpleNumber('gcd', this, adverb) }
85 round { arg aNumber=1.0, adverb; _Round; ^aNumber.performBinaryOpOnSimpleNumber('round', this, adverb) }
86 roundUp { arg aNumber=1.0, adverb; _RoundUp; ^aNumber.performBinaryOpOnSimpleNumber('roundUp', this, adverb) }
87 trunc { arg aNumber=1.0, adverb; _Trunc; ^aNumber.performBinaryOpOnSimpleNumber('trunc', this, adverb) }
88 atan2 { arg aNumber, adverb; _Atan2; ^aNumber.performBinaryOpOnSimpleNumber('atan2', this, adverb) }
89 hypot { arg aNumber, adverb; _Hypot; ^aNumber.performBinaryOpOnSimpleNumber('hypot', this, adverb) }
90 hypotApx { arg aNumber, adverb; _HypotApx; ^aNumber.performBinaryOpOnSimpleNumber('hypotApx', this, adverb) }
91 leftShift { arg aNumber=1, adverb; _ShiftLeft; ^aNumber.performBinaryOpOnSimpleNumber('leftShift', this, adverb) }
92 rightShift { arg aNumber=1, adverb; _ShiftRight; ^aNumber.performBinaryOpOnSimpleNumber('rightShift', this, adverb) }
93 unsignedRightShift { arg aNumber, adverb; _UnsignedShift; ^aNumber.performBinaryOpOnSimpleNumber('unsignedRightShift', this, adverb) }
94 ring1 { arg aNumber, adverb; _Ring1; ^aNumber.performBinaryOpOnSimpleNumber('ring1', this, adverb) }
95 ring2 { arg aNumber, adverb; _Ring2; ^aNumber.performBinaryOpOnSimpleNumber('ring2', this, adverb) }
96 ring3 { arg aNumber, adverb; _Ring3; ^aNumber.performBinaryOpOnSimpleNumber('ring3', this, adverb) }
97 ring4 { arg aNumber, adverb; _Ring4; ^aNumber.performBinaryOpOnSimpleNumber('ring4', this, adverb) }
98 difsqr { arg aNumber, adverb; _DifSqr; ^aNumber.performBinaryOpOnSimpleNumber('difsqr', this, adverb) }
99 sumsqr { arg aNumber, adverb; _SumSqr; ^aNumber.performBinaryOpOnSimpleNumber('sumsqr', this, adverb) }
100 sqrsum { arg aNumber, adverb; _SqrSum; ^aNumber.performBinaryOpOnSimpleNumber('sqrsum', this, adverb) }
101 sqrdif { arg aNumber, adverb; _SqrDif; ^aNumber.performBinaryOpOnSimpleNumber('sqrdif', this, adverb) }
102 absdif { arg aNumber, adverb; _AbsDif; ^aNumber.performBinaryOpOnSimpleNumber('absdif', this, adverb) }
103 thresh { arg aNumber, adverb; _Thresh; ^aNumber.performBinaryOpOnSimpleNumber('thresh', this, adverb) }
104 amclip { arg aNumber, adverb; _AMClip; ^aNumber.performBinaryOpOnSimpleNumber('amclip', this, adverb) }
105 scaleneg { arg aNumber, adverb; _ScaleNeg; ^aNumber.performBinaryOpOnSimpleNumber('scaleneg', this, adverb) }
106 clip2 { arg aNumber, adverb; _Clip2; ^aNumber.performBinaryOpOnSimpleNumber('clip2', this, adverb) }
107 fold2 { arg aNumber, adverb; _Fold2; ^aNumber.performBinaryOpOnSimpleNumber('fold2', this, adverb) }
108 wrap2 { arg aNumber, adverb; _Wrap2; ^aNumber.performBinaryOpOnSimpleNumber('wrap2', this, adverb) }
110 excess { arg aNumber, adverb; _Excess; ^aNumber.performBinaryOpOnSimpleNumber('excess', this, adverb) }
111 firstArg { arg aNumber, adverb; _FirstArg; ^aNumber.performBinaryOpOnSimpleNumber('firstArg', this, adverb) }
112 rrand { arg aNumber, adverb; _RandRange; ^aNumber.performBinaryOpOnSimpleNumber('rrand', this, adverb) }
113 exprand { arg aNumber, adverb; _ExpRandRange; ^aNumber.performBinaryOpOnSimpleNumber('exprand', this, adverb) }
115 == { arg aNumber, adverb; _EQ; ^aNumber.perform('==', this, adverb) }
116 != { arg aNumber, adverb; _NE; ^aNumber.perform('!=', this, adverb) }
117 < { arg aNumber, adverb; _LT; ^aNumber.performBinaryOpOnSimpleNumber('<', this, adverb) }
118 > { arg aNumber, adverb; _GT; ^aNumber.performBinaryOpOnSimpleNumber('>', this, adverb) }
119 <= { arg aNumber, adverb; _LE; ^aNumber.performBinaryOpOnSimpleNumber('<=', this, adverb) }
120 >= { arg aNumber, adverb; _GE; ^aNumber.performBinaryOpOnSimpleNumber('>=', this, adverb) }
122 equalWithPrecision { arg that, precision=0.0001;
123 ^absdif(this, that) < precision
126 hash { _ObjectHash; ^this.primitiveFailed }
128 asInteger { _AsInt; ^this.primitiveFailed }
129 asFloat { _AsFloat; ^this.primitiveFailed }
130 asComplex { ^Complex.new(this, 0.0) }
131 asRect { ^Rect(this, this, this, this) }
133 degrad { ^this*pi/180 }
134 raddeg { ^this*180/pi }
138 performBinaryOpOnSimpleNumber { arg aSelector, aNumber; ^error("Math operation failed.\n") }
139 performBinaryOpOnComplex { arg aSelector, aComplex, adverb; ^aComplex.perform(aSelector, this.asComplex, adverb) }
140 performBinaryOpOnSignal { arg aSelector, aSignal; ^error("Math operation failed.\n") }
142 nextPowerOfTwo { ^this.nextPowerOf(2) }
143 nextPowerOf { arg base; ^pow(base, ceil(log(this) / log(base))) }
144 nextPowerOfThree { ^pow(3, ceil(log(this) / log(3))) }
145 previousPowerOf { arg base; ^pow(base, ceil(log(this) / log(base)) - 1) }
147 quantize { arg quantum = 1.0, tolerance = 0.05, strength = 1.0;
148 var round = round(this, quantum);
149 var diff = round - this;
150 if (abs(diff) < tolerance) {
151 ^this + (strength * diff)
158 linlin { arg inMin, inMax, outMin, outMax, clip=\minmax;
159 // linear to linear mapping
162 if (this <= inMin, { ^outMin });
163 if (this >= inMax, { ^outMax });
166 if (this <= inMin, { ^outMin });
169 if (this >= inMax, { ^outMax });
172 ^(this-inMin)/(inMax-inMin) * (outMax-outMin) + outMin;
175 linexp { arg inMin, inMax, outMin, outMax, clip=\minmax;
176 // linear to exponential mapping
179 if (this <= inMin, { ^outMin });
180 if (this >= inMax, { ^outMax });
183 if (this <= inMin, { ^outMin });
186 if (this >= inMax, { ^outMax });
189 ^pow(outMax/outMin, (this-inMin)/(inMax-inMin)) * outMin
192 explin { arg inMin, inMax, outMin, outMax, clip=\minmax;
193 // exponential to linear mapping
196 if (this <= inMin, { ^outMin });
197 if (this >= inMax, { ^outMax });
200 if (this <= inMin, { ^outMin });
203 if (this >= inMax, { ^outMax });
206 ^(log(this/inMin)) / (log(inMax/inMin)) * (outMax-outMin) + outMin;
209 expexp { arg inMin, inMax, outMin, outMax, clip=\minmax;
210 // exponential to exponential mapping
213 if (this <= inMin, { ^outMin });
214 if (this >= inMax, { ^outMax });
217 if (this <= inMin, { ^outMin });
220 if (this >= inMax, { ^outMax });
223 ^pow(outMax/outMin, log(this/inMin) / log(inMax/inMin)) * outMin;
226 lincurve { arg inMin = 0, inMax = 1, outMin = 0, outMax = 1, curve = -4, clip = \minmax;
227 var grow, a, b, scaled;
230 if (this <= inMin, { ^outMin });
231 if (this >= inMax, { ^outMax });
234 if (this <= inMin, { ^outMin });
237 if (this >= inMax, { ^outMax });
240 if (abs(curve) < 0.001) { ^this.linlin(inMin, inMax, outMin, outMax) };
243 a = outMax - outMin / (1.0 - grow);
245 scaled = (this - inMin) / (inMax - inMin);
247 ^b - (a * pow(grow, scaled));
250 curvelin { arg inMin = 0, inMax = 1, outMin = 0, outMax = 1, curve = -4, clip = \minmax;
251 var grow, a, b, scaled;
254 if (this <= inMin, { ^outMin });
255 if (this >= inMax, { ^outMax });
258 if (this <= inMin, { ^outMin });
261 if (this >= inMax, { ^outMax });
264 if (abs(curve) < 0.001) { ^this.linlin(inMin, inMax, outMin, outMax) };
267 a = outMax - outMin / (1.0 - grow);
269 scaled = (this - inMin) / (inMax - inMin);
271 ^log((b - scaled) / a) / curve
274 bilin { arg inCenter, inMin, inMax, outCenter, outMin, outMax, clip=\minmax;
275 // triangular linear mapping
278 if (this <= inMin, { ^outMin });
279 if (this >= inMax, { ^outMax });
282 if (this <= inMin, { ^outMin });
285 if (this >= inMax, { ^outMax });
288 ^if (this >= inCenter) {
289 this.linlin(inCenter, inMax, outCenter, outMax, \none);
291 this.linlin(inMin, inCenter, outMin, outCenter, \none);
295 biexp { arg inCenter, inMin, inMax, outCenter, outMin, outMax, clip=\minmax;
296 // triangular exponential mapping
299 if (this <= inMin, { ^outMin });
300 if (this >= inMax, { ^outMax });
303 if (this <= inMin, { ^outMin });
306 if (this >= inMax, { ^outMax });
309 if (this >= inCenter) {
310 this.explin(inCenter, inMax, outCenter, outMax, \none);
312 this.explin(inMin, inCenter, outMin, outCenter, \none);
315 lcurve { arg a = 1.0, m = 0.0, n = 1.0, tau = 1.0;
316 var rTau, x = this.neg;
318 a * (m * exp(x) + 1) / (n * exp(x) + 1)
320 rTau = tau.reciprocal;
321 a * (m * exp(x) * rTau + 1) / (n * exp(x) * rTau + 1)
324 gauss { arg standardDeviation;
325 ^((((-2*log(1.0.rand)).sqrt * sin(2pi.rand)) * standardDeviation) + this)
327 gaussCurve { arg a = 1.0, b = 0.0, c = 1.0;
328 ^a * (exp(squared(this - b) / (-2.0 * squared(c))))
331 asPoint { ^Point.new(this, this) }
333 asWarp { arg spec; ^CurveWarp.new(spec, this) }
335 // scheduled Routine support
337 waitUntil { ^(this - thisThread.beats).max(0).yield }
339 var thread = thisThread;
340 thread.clock.sched(this, { thread.next; nil });
344 printOn { arg stream;
345 stream.putAll(this.asString);
347 storeOn { arg stream;
348 stream.putAll(this.asString);
352 rate { ^'scalar' } // scalarRate constant
353 asAudioRateInput { ^if(this == 0) { Silent.ar } { DC.ar(this) } }
355 // support for writing synth defs
356 writeInputSpec { arg file, synth;
357 var constIndex = synth.constants.at(this.asFloat);
358 if (constIndex.isNil) {
359 Error("SimpleNumber-writeInputSpec constant not found: " ++ this.asFloat).throw; };
360 //[\inpspc, this.class.name, constIndex, this].postln;
362 file.putInt16(constIndex);
365 series { arg second, last;
367 ^this.primitiveFailed
369 second = second ?? { if (this < last) { this + 1 } { this - 1 } };
370 step = second - this;
371 size = floor((last - this) / step + 0.001).asInteger + 1;
372 ^Array.series(size, this, step) */
374 seriesIter { arg second, last;
378 step = if (this < last, 1, -1);
380 last ?? { last = if (second < this, -inf, inf) };
381 step = second - this;
407 degreeToKey { arg scale, stepsPerOctave = 12;
408 var scaleDegree = this.round.asInteger;
409 var accidental = (this - scaleDegree) * 10.0;
410 ^scale.performDegreeToKey(scaleDegree, stepsPerOctave, accidental)
413 keyToDegree { arg scale, stepsPerOctave=12;
414 var n = this div: stepsPerOctave * scale.size;
415 var key = this % stepsPerOctave;
416 ^scale.indexInBetween(key) + n
419 nearestInList { arg list; // collection is sorted
420 ^list.performNearestInList(this);
423 nearestInScale { arg scale, stepsPerOctave=12; // collection is sorted
424 ^scale.performNearestInScale(this, stepsPerOctave);
427 partition { arg parts=2, min=1;
428 // randomly partition a number into parts of at least min size :
429 var n = this - (min - 1 * parts);
430 ^(1..n-1).scramble.keep(parts-1).sort.add(n).differentiate + (min - 1)
433 nextTimeOnGrid { arg clock;
434 ^clock.nextTimeOnGrid(this, 0);
439 asQuant { ^Quant(this) }
441 // a clock format inspired by ISO 8601 time interval display (truncated representation)
442 // receiver is a time in seconds, returns string "ddd:hh:mm:ss:ttt" where t is milliseconds
443 // see String:asSecs for complement
445 asTimeString { arg precision = 0.001, maxDays = 365, dropDaysIfPossible = true;
446 var decimal, days, hours, minutes, seconds, mseconds;
447 decimal = this.asInteger;
448 days = decimal.div(86400).min(maxDays);
449 days = if(dropDaysIfPossible and: { days == 0 }) {
452 days.asString.padLeft(3, "0").add($:);
454 hours = (decimal.div(3600) % 24).asString.padLeft(2, "0").add($:);
455 minutes = (decimal.div(60) % 60).asString.padLeft(2, "0").add($:);
456 seconds = (decimal % 60).asString.padLeft(2, "0").add($:);
457 mseconds = (this.frac / precision).round(precision).asInteger.asString.padLeft(3, "0");
458 ^days ++ hours ++ minutes ++ seconds ++ mseconds
461 asFraction {|denominator=100, fasterBetter=true|
463 // asFraction will return a fraction that is the best approximation up to the given
465 // if fasterBetter is true it may find a much closer approximation and do it faster.
466 ^this.primitiveFailed
468 prSimpleNumberSeries { arg second, last;
470 ^this.primitiveFailed
477 schedBundleArrayOnClock { |clock, bundleArray, lag = 0, server, latency|
480 SystemClock.sched(lag, {
481 server.sendBundle(latency ? server.latency, *bundleArray)
484 server.sendBundle(latency ? server.latency, *bundleArray)