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 }
136 performBinaryOpOnSimpleNumber { arg aSelector, aNumber, adverb;
137 BinaryOpFailureError(this, aSelector, [aNumber, adverb]).throw;
139 performBinaryOpOnComplex { arg aSelector, aComplex, adverb; ^aComplex.perform(aSelector, this.asComplex, adverb) }
140 performBinaryOpOnSignal { arg aSelector, aSignal, adverb;
141 BinaryOpFailureError(this, aSelector, [aSignal, adverb]).throw;
144 nextPowerOfTwo { ^this.nextPowerOf(2) }
145 nextPowerOf { arg base; ^pow(base, ceil(log(this) / log(base))) }
146 nextPowerOfThree { ^pow(3, ceil(log(this) / log(3))) }
147 previousPowerOf { arg base; ^pow(base, ceil(log(this) / log(base)) - 1) }
149 quantize { arg quantum = 1.0, tolerance = 0.05, strength = 1.0;
150 var round = round(this, quantum);
151 var diff = round - this;
152 if (abs(diff) < tolerance) {
153 ^this + (strength * diff)
160 linlin { arg inMin, inMax, outMin, outMax, clip=\minmax;
161 // linear to linear mapping
164 if (this <= inMin, { ^outMin });
165 if (this >= inMax, { ^outMax });
168 if (this <= inMin, { ^outMin });
171 if (this >= inMax, { ^outMax });
174 ^(this-inMin)/(inMax-inMin) * (outMax-outMin) + outMin;
177 linexp { arg inMin, inMax, outMin, outMax, clip=\minmax;
178 // linear to exponential mapping
181 if (this <= inMin, { ^outMin });
182 if (this >= inMax, { ^outMax });
185 if (this <= inMin, { ^outMin });
188 if (this >= inMax, { ^outMax });
191 ^pow(outMax/outMin, (this-inMin)/(inMax-inMin)) * outMin
194 explin { arg inMin, inMax, outMin, outMax, clip=\minmax;
195 // exponential to linear mapping
198 if (this <= inMin, { ^outMin });
199 if (this >= inMax, { ^outMax });
202 if (this <= inMin, { ^outMin });
205 if (this >= inMax, { ^outMax });
208 ^(log(this/inMin)) / (log(inMax/inMin)) * (outMax-outMin) + outMin;
211 expexp { arg inMin, inMax, outMin, outMax, clip=\minmax;
212 // exponential to exponential mapping
215 if (this <= inMin, { ^outMin });
216 if (this >= inMax, { ^outMax });
219 if (this <= inMin, { ^outMin });
222 if (this >= inMax, { ^outMax });
225 ^pow(outMax/outMin, log(this/inMin) / log(inMax/inMin)) * outMin;
228 lincurve { arg inMin = 0, inMax = 1, outMin = 0, outMax = 1, curve = -4, clip = \minmax;
229 var grow, a, b, scaled;
232 if (this <= inMin, { ^outMin });
233 if (this >= inMax, { ^outMax });
236 if (this <= inMin, { ^outMin });
239 if (this >= inMax, { ^outMax });
242 if (abs(curve) < 0.001) { ^this.linlin(inMin, inMax, outMin, outMax) };
245 a = outMax - outMin / (1.0 - grow);
247 scaled = (this - inMin) / (inMax - inMin);
249 ^b - (a * pow(grow, scaled));
252 curvelin { arg inMin = 0, inMax = 1, outMin = 0, outMax = 1, curve = -4, clip = \minmax;
253 var grow, a, b, scaled;
256 if (this <= inMin, { ^outMin });
257 if (this >= inMax, { ^outMax });
260 if (this <= inMin, { ^outMin });
263 if (this >= inMax, { ^outMax });
266 if (abs(curve) < 0.001) { ^this.linlin(inMin, inMax, outMin, outMax) };
269 a = outMax - outMin / (1.0 - grow);
271 scaled = (this - inMin) / (inMax - inMin);
273 ^log((b - scaled) / a) / curve
276 bilin { arg inCenter, inMin, inMax, outCenter, outMin, outMax, clip=\minmax;
277 // triangular linear mapping
280 if (this <= inMin, { ^outMin });
281 if (this >= inMax, { ^outMax });
284 if (this <= inMin, { ^outMin });
287 if (this >= inMax, { ^outMax });
290 ^if (this >= inCenter) {
291 this.linlin(inCenter, inMax, outCenter, outMax, \none);
293 this.linlin(inMin, inCenter, outMin, outCenter, \none);
297 biexp { arg inCenter, inMin, inMax, outCenter, outMin, outMax, clip=\minmax;
298 // triangular exponential mapping
301 if (this <= inMin, { ^outMin });
302 if (this >= inMax, { ^outMax });
305 if (this <= inMin, { ^outMin });
308 if (this >= inMax, { ^outMax });
311 if (this >= inCenter) {
312 this.explin(inCenter, inMax, outCenter, outMax, \none);
314 this.explin(inMin, inCenter, outMin, outCenter, \none);
317 lcurve { arg a = 1.0, m = 0.0, n = 1.0, tau = 1.0;
318 var rTau, x = this.neg;
320 a * (m * exp(x) + 1) / (n * exp(x) + 1)
322 rTau = tau.reciprocal;
323 a * (m * exp(x) * rTau + 1) / (n * exp(x) * rTau + 1)
326 gauss { arg standardDeviation;
327 ^((((-2*log(1.0.rand)).sqrt * sin(2pi.rand)) * standardDeviation) + this)
329 gaussCurve { arg a = 1.0, b = 0.0, c = 1.0;
330 ^a * (exp(squared(this - b) / (-2.0 * squared(c))))
333 asPoint { ^Point.new(this, this) }
335 asWarp { arg spec; ^CurveWarp.new(spec, this) }
337 // scheduled Routine support
339 waitUntil { ^(this - thisThread.beats).max(0).yield }
341 var thread = thisThread;
342 thread.clock.sched(this, { thread.next; nil });
346 printOn { arg stream;
347 stream.putAll(this.asString);
349 storeOn { arg stream;
350 stream.putAll(this.asString);
354 rate { ^'scalar' } // scalarRate constant
355 asAudioRateInput { ^if(this == 0) { Silent.ar } { DC.ar(this) } }
357 madd { arg mul, add; ^(this * mul) + add; }
368 // support for writing synth defs
369 writeInputSpec { arg file, synth;
370 var constIndex = synth.constants.at(this.asFloat);
371 if (constIndex.isNil) {
372 Error("SimpleNumber-writeInputSpec constant not found: " ++ this.asFloat).throw;
375 file.putInt32(constIndex);
378 series { arg second, last;
380 ^this.primitiveFailed
382 second = second ?? { if (this < last) { this + 1 } { this - 1 } };
383 step = second - this;
384 size = floor((last - this) / step + 0.001).asInteger + 1;
385 ^Array.series(size, this, step) */
387 seriesIter { arg second, last;
391 step = if (this < last, 1, -1);
393 last ?? { last = if (second < this, -inf, inf) };
394 step = second - this;
420 degreeToKey { arg scale, stepsPerOctave = 12;
421 var scaleDegree = this.round.asInteger;
422 var accidental = (this - scaleDegree) * 10.0;
423 ^scale.performDegreeToKey(scaleDegree, stepsPerOctave, accidental)
426 keyToDegree { arg scale, stepsPerOctave=12;
427 ^scale.performKeyToDegree(this, stepsPerOctave)
430 nearestInList { arg list; // collection is sorted
431 ^list.performNearestInList(this);
434 nearestInScale { arg scale, stepsPerOctave=12; // collection is sorted
435 ^scale.performNearestInScale(this, stepsPerOctave);
438 partition { arg parts=2, min=1;
439 // randomly partition a number into parts of at least min size :
440 var n = this - (min - 1 * parts);
441 ^(1..n-1).scramble.keep(parts-1).sort.add(n).differentiate + (min - 1)
444 nextTimeOnGrid { arg clock;
445 ^clock.nextTimeOnGrid(this, 0);
450 asQuant { ^Quant(this) }
452 // a clock format inspired by ISO 8601 time interval display (truncated representation)
453 // receiver is a time in seconds, returns string "ddd:hh:mm:ss:ttt" where t is milliseconds
454 // see String:asSecs for complement
456 asTimeString { arg precision = 0.001, maxDays = 365, dropDaysIfPossible = true;
457 var decimal, days, hours, minutes, seconds, mseconds;
458 decimal = this.asInteger;
459 days = decimal.div(86400).min(maxDays);
460 days = if(dropDaysIfPossible and: { days == 0 }) {
463 days.asString.padLeft(3, "0").add($:);
465 hours = (decimal.div(3600) % 24).asString.padLeft(2, "0").add($:);
466 minutes = (decimal.div(60) % 60).asString.padLeft(2, "0").add($:);
467 seconds = (decimal % 60).asString.padLeft(2, "0").add($:);
468 mseconds = (this.frac / precision).round(precision).asInteger.asString.padLeft(3, "0");
469 ^days ++ hours ++ minutes ++ seconds ++ mseconds
472 asFraction {|denominator=100, fasterBetter=true|
474 // asFraction will return a fraction that is the best approximation up to the given
476 // if fasterBetter is true it may find a much closer approximation and do it faster.
477 ^this.primitiveFailed
479 prSimpleNumberSeries { arg second, last;
481 ^this.primitiveFailed
488 schedBundleArrayOnClock { |clock, bundleArray, lag = 0, server, latency|
491 SystemClock.sched(lag, {
492 server.sendBundle(latency ? server.latency, *bundleArray)
495 server.sendBundle(latency ? server.latency, *bundleArray)