1SimpleNumber : Number { 2 3 *new { ^this.shouldNotImplement(thisMethod) } 4 5 isValidUGenInput { ^this.isNaN.not } 6 numChannels { ^1 } 7 8 magnitude { ^this.abs } 9 angle { ^if(this >= 0) { 0.0 } { pi } } 10 11 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 } 49 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 60 61 rectWindow { _RectWindow; ^this.primitiveFailed } 62 hanWindow { _HanWindow; ^this.primitiveFailed } 63 welWindow { _WelchWindow; ^this.primitiveFailed } 64 triWindow { _TriWindow; ^this.primitiveFailed } 65 66 scurve { _SCurve; ^this.primitiveFailed } 67 ramp { _Ramp; ^this.primitiveFailed } 68 69 + { |aNumber, adverb| _Add; ^aNumber.performBinaryOpOnSimpleNumber('+', this, adverb) } 70 - { |aNumber, adverb| _Sub; ^aNumber.performBinaryOpOnSimpleNumber('-', this, adverb) } 71 * { |aNumber, adverb| _Mul; ^aNumber.performBinaryOpOnSimpleNumber('*', this, adverb) } 72 / { |aNumber, adverb| _FDiv; ^aNumber.performBinaryOpOnSimpleNumber('/', this, adverb) } 73 mod { |aNumber, adverb| _Mod; ^aNumber.performBinaryOpOnSimpleNumber('mod', this, adverb) } 74 div { |aNumber, adverb| _IDiv; ^aNumber.performBinaryOpOnSimpleNumber('div', this, adverb) } 75 pow { |aNumber, adverb| _Pow; ^aNumber.performBinaryOpOnSimpleNumber('pow', this, adverb) } 76 min { |aNumber, adverb| _Min; ^aNumber.performBinaryOpOnSimpleNumber('min', this, adverb) } 77 max { |aNumber=0.0, adverb| _Max; ^aNumber.performBinaryOpOnSimpleNumber('max', this, adverb) } 78 bitAnd { |aNumber, adverb| _BitAnd; ^aNumber.performBinaryOpOnSimpleNumber('bitAnd', this, adverb) } 79 bitOr { |aNumber, adverb| _BitOr; ^aNumber.performBinaryOpOnSimpleNumber('bitOr', this, adverb) } 80 bitXor { |aNumber, adverb| _BitXor; ^aNumber.performBinaryOpOnSimpleNumber('bitXor', this, adverb) } 81 bitHammingDistance { |aNumber, adverb| _HammingDistance ^aNumber.performBinaryOpOnSimpleNumber('hammingDistance', this, adverb) } 82 bitTest { arg bit; ^( (this.bitAnd(1.leftShift(bit))) != 0) } 83 lcm { |aNumber, adverb| _LCM; ^aNumber.performBinaryOpOnSimpleNumber('lcm', this, adverb) } 84 gcd { |aNumber, adverb| _GCD; ^aNumber.performBinaryOpOnSimpleNumber('gcd', this, adverb) } 85 round { |aNumber=1.0, adverb| _Round; ^aNumber.performBinaryOpOnSimpleNumber('round', this, adverb) } 86 roundUp { |aNumber=1.0, adverb| _RoundUp; ^aNumber.performBinaryOpOnSimpleNumber('roundUp', this, adverb) } 87 trunc { |aNumber=1.0, adverb| _Trunc; ^aNumber.performBinaryOpOnSimpleNumber('trunc', this, adverb) } 88 atan2 { |aNumber, adverb| _Atan2; ^aNumber.performBinaryOpOnSimpleNumber('atan2', this, adverb) } 89 hypot { |aNumber, adverb| _Hypot; ^aNumber.performBinaryOpOnSimpleNumber('hypot', this, adverb) } 90 hypotApx { |aNumber, adverb| _HypotApx; ^aNumber.performBinaryOpOnSimpleNumber('hypotApx', this, adverb) } 91 leftShift { |aNumber=1, adverb| _ShiftLeft; ^aNumber.performBinaryOpOnSimpleNumber('leftShift', this, adverb) } 92 rightShift { |aNumber=1, adverb| _ShiftRight; ^aNumber.performBinaryOpOnSimpleNumber('rightShift', this, adverb) } 93 unsignedRightShift { |aNumber, adverb| _UnsignedShift; ^aNumber.performBinaryOpOnSimpleNumber('unsignedRightShift', this, adverb) } 94 ring1 { |aNumber, adverb| _Ring1; ^aNumber.performBinaryOpOnSimpleNumber('ring1', this, adverb) } 95 ring2 { |aNumber, adverb| _Ring2; ^aNumber.performBinaryOpOnSimpleNumber('ring2', this, adverb) } 96 ring3 { |aNumber, adverb| _Ring3; ^aNumber.performBinaryOpOnSimpleNumber('ring3', this, adverb) } 97 ring4 { |aNumber, adverb| _Ring4; ^aNumber.performBinaryOpOnSimpleNumber('ring4', this, adverb) } 98 difsqr { |aNumber, adverb| _DifSqr; ^aNumber.performBinaryOpOnSimpleNumber('difsqr', this, adverb) } 99 sumsqr { |aNumber, adverb| _SumSqr; ^aNumber.performBinaryOpOnSimpleNumber('sumsqr', this, adverb) } 100 sqrsum { |aNumber, adverb| _SqrSum; ^aNumber.performBinaryOpOnSimpleNumber('sqrsum', this, adverb) } 101 sqrdif { |aNumber, adverb| _SqrDif; ^aNumber.performBinaryOpOnSimpleNumber('sqrdif', this, adverb) } 102 absdif { |aNumber, adverb| _AbsDif; ^aNumber.performBinaryOpOnSimpleNumber('absdif', this, adverb) } 103 thresh { |aNumber, adverb| _Thresh; ^aNumber.performBinaryOpOnSimpleNumber('thresh', this, adverb) } 104 amclip { |aNumber, adverb| _AMClip; ^aNumber.performBinaryOpOnSimpleNumber('amclip', this, adverb) } 105 scaleneg { |aNumber, adverb| _ScaleNeg; ^aNumber.performBinaryOpOnSimpleNumber('scaleneg', this, adverb) } 106 clip2 { |aNumber=1, adverb| _Clip2; ^aNumber.performBinaryOpOnSimpleNumber('clip2', this, adverb) } 107 fold2 { |aNumber=1, adverb| _Fold2; ^aNumber.performBinaryOpOnSimpleNumber('fold2', this, adverb) } 108 wrap2 { |aNumber=1, adverb| _Wrap2; ^aNumber.performBinaryOpOnSimpleNumber('wrap2', this, adverb) } 109 110 excess { |aNumber=1, adverb| _Excess; ^aNumber.performBinaryOpOnSimpleNumber('excess', this, adverb) } 111 firstArg { |aNumber, adverb| _FirstArg; ^aNumber.performBinaryOpOnSimpleNumber('firstArg', this, adverb) } 112 rrand { |aNumber, adverb| _RandRange; ^aNumber.performBinaryOpOnSimpleNumber('rrand', this, adverb) } 113 exprand { |aNumber, adverb| _ExpRandRange; ^aNumber.performBinaryOpOnSimpleNumber('exprand', this, adverb) } 114 115 == { |aNumber, adverb| _EQ; ^aNumber.perform('==', this, adverb) } 116 != { |aNumber, adverb| _NE; ^aNumber.perform('!=', this, adverb) } 117 < { |aNumber, adverb| _LT; ^aNumber.performBinaryOpOnSimpleNumber('<', this, adverb) } 118 > { |aNumber, adverb| _GT; ^aNumber.performBinaryOpOnSimpleNumber('>', this, adverb) } 119 <= { |aNumber, adverb| _LE; ^aNumber.performBinaryOpOnSimpleNumber('<=', this, adverb) } 120 >= { |aNumber, adverb| _GE; ^aNumber.performBinaryOpOnSimpleNumber('>=', this, adverb) } 121 122 equalWithPrecision { |that, precision = 0.0001, relativePrecision = 0| 123 ^if(relativePrecision > 0) { 124 absdif(this, that) < max(precision, relativePrecision * min(abs(this), abs(that))) 125 } { 126 absdif(this, that) < precision 127 } 128 } 129 130 hash { _ObjectHash; ^this.primitiveFailed } 131 132 asInteger { _AsInteger; ^this.primitiveFailed } 133 asFloat { _AsFloat; ^this.primitiveFailed } 134 asComplex { ^Complex.new(this, 0.0) } 135 asRect { ^Rect(this, this, this, this) } 136 137 degrad { ^this * pi / 180 } 138 raddeg { ^this * 180 / pi } 139 140 performBinaryOpOnSimpleNumber { |aSelector, aNumber, adverb| 141 BinaryOpFailureError(this, aSelector, [aNumber, adverb]).throw; 142 } 143 performBinaryOpOnComplex { |aSelector, aComplex, adverb| ^aComplex.perform(aSelector, this.asComplex, adverb) } 144 performBinaryOpOnSignal { |aSelector, aSignal, adverb| 145 BinaryOpFailureError(this, aSelector, [aSignal, adverb]).throw; 146 } 147 148 nextPowerOfTwo { ^this.nextPowerOf(2) } 149 nextPowerOf { |base| ^pow(base, ceil(log(this) / log(base))) } 150 nextPowerOfThree { ^pow(3, ceil(log(this) / log(3))) } 151 previousPowerOf { |base| ^pow(base, ceil(log(this) / log(base)) - 1) } 152 153 154 /* Boost Special Functions */ 155 156 // Number Series: 157 bernouliB2n { _BernouliB2n; ^this.primitiveFailed } 158 tangentT2n { _TangentT2n; ^this.primitiveFailed } 159 160 // Gamma: 161 tgamma { _TGamma; ^this.primitiveFailed } 162 tgamma1pm1 { _TGamma1pm1; ^this.primitiveFailed } 163 lgamma { _LGamma; ^this.primitiveFailed } 164 digamma { _Digamma; ^this.primitiveFailed } 165 trigamma { _Trigamma; ^this.primitiveFailed } 166 polygamma { |z| _Polygamma; ^this.primitiveFailed } 167 tgammaRatio { |b| _TGammaRatio; ^this.primitiveFailed } 168 tgammaDeltaRatio { |delta| _TGammaDeltaRatio; ^this.primitiveFailed } 169 gammaP { |z| _GammaP; ^this.primitiveFailed } 170 gammaQ { |z| _GammaQ; ^this.primitiveFailed } 171 tgammaLower { |z| _TGammaLower; ^this.primitiveFailed } 172 tgammaUpper { |z| _TGammaI; ^this.primitiveFailed } 173 // Incomplete Gamma Function Inverses 174 gammaPInv { |p| _GammaPInv; ^this.primitiveFailed } 175 gammaQInv { |q| _GammaQInv; ^this.primitiveFailed } 176 gammaPInvA { |p| _GammaPInvA; ^this.primitiveFailed } 177 gammaQInvA { |q| _GammaQInvA; ^this.primitiveFailed } 178 // Derivatives of the Incomplete Gamma Function 179 gammaPDerivative { |x| _GammaPDerivative; ^this.primitiveFailed } 180 gammaQDerivative { |x| ^this.gammaPDerivative(x).neg } 181 182 // Factorials and Binomial Coefficients: 183 factorial { _Factorial; ^this.primitiveFailed } 184 doubleFactorial { _DoubleFactorial; ^this.primitiveFailed } 185 risingFactorial { |i| _RisingFactorial; ^this.primitiveFailed } 186 fallingFactorial { |i| _FallingFactorial; ^this.primitiveFailed } 187 binomialCoefficient { |k| _BinomialCoefficient; ^this.primitiveFailed } 188 189 // Beta functions: 190 beta { |b| _Beta; ^this.primitiveFailed } 191 // Incomplete beta functions 192 ibeta { |b, x| _IBeta; ^this.primitiveFailed } 193 ibetaC { |b, x| _IBetaC; ^this.primitiveFailed } 194 betaFull { |b, x| _BetaFull; ^this.primitiveFailed } 195 betaFullC { |b, x| _BetaCFull; ^this.primitiveFailed } 196 // Incomplete beta function inverses 197 ibetaInv { |b, p| _IBetaInv; ^this.primitiveFailed } 198 ibetaCInv { |b, q| _IBetaCInv; ^this.primitiveFailed } 199 ibetaInvA { |x, p| _IBetaInvA; ^this.primitiveFailed } 200 ibetaCInvA { |x, q| _IBetaCInvA; ^this.primitiveFailed } 201 ibetaInvB { |x, p| _IBetaInvB; ^this.primitiveFailed } 202 ibetaCInvB { |x, q| _IBetaCInvB; ^this.primitiveFailed } 203 // Incomplete beta function derivative 204 ibetaDerivative { |b, x| _IBetaDerivative; ^this.primitiveFailed } 205 206 // Error functions: 207 erf { _Erf; ^this.primitiveFailed } 208 erfC { _ErfC; ^this.primitiveFailed } 209 erfInv { _ErfInv; ^this.primitiveFailed } 210 erfCInv { _ErfCInv; ^this.primitiveFailed } 211 212 // Polynomials: 213 // Legendre (and Associated), Laguerre (and Associated), 214 // Hermite, Chebyshev Polynomials (first & second kind, derivative, zero (root) finder) 215 // See boost documentation for a note about the Condon-Shortley phase term of (-1)^m 216 // "http://www.boost.org/doc/libs/1_65_1/libs/math/doc/html/math_toolkit/sf_poly/legendre.html"] 217 legendreP { |x| _LegendreP; ^this.primitiveFailed } 218 legendrePPrime { |x| _LegendrePPrime; ^this.primitiveFailed } 219 legendrePZeros { _LegendrePZeros; ^this.primitiveFailed } 220 legendrePAssoc { |m, x| _LegendrePAssoc; ^this.primitiveFailed } 221 legendreQ { |x| 222 // Protect from l < 0. Boost won't catch this out of range value and interpreter hangs. 223 if(this < 0) { 224 format("n = %, but Legendre Polynomial of the Second Kind requires n >= 0", this).throw 225 }; 226 ^prLegendreQ(this, x) 227 } 228 prLegendreQ { |x| _LegendreQ; ^this.primitiveFailed } 229 laguerre { |x| _Laguerre; ^this.primitiveFailed } 230 laguerreAssoc { |m, x| 231 // Protect from m < 0. Boost won't catch this out of range value and interpreter hangs. 232 if(this < 0) { 233 format("n = %, but Associated Laguerre Polynomial requires n >= 0", this).throw 234 }; 235 ^prLaguerreAssoc(this, m, x) 236 } 237 prLaguerreAssoc { |m, x| _LaguerreAssoc; ^this.primitiveFailed } 238 hermite { |x| 239 // Protect from m < 0. Boost won't catch this out of range value and interpreter hangs. 240 if(this < 0) { 241 format("n = %, but Hermite Polynomial requires n >= 0", this).throw 242 }; 243 ^prHermite(this, x) 244 } 245 prHermite { |x| _Hermite; ^this.primitiveFailed } 246 chebyshevT { |x| _ChebyshevT; ^this.primitiveFailed } 247 chebyshevU { |x| _ChebyshevU; ^this.primitiveFailed } 248 chebyshevTPrime { |x| _ChebyshevTPrime; ^this.primitiveFailed } 249 // "https://en.wikipedia.org/wiki/Chebyshev_polynomials#Roots_and_extrema" 250 // "http://mathworld.wolfram.com/ChebyshevPolynomialoftheFirstKind.html" 251 chebyshevTZeros { 252 var n = this.asInteger; 253 ^(1..n).collect { |k| 254 cos(pi * ((2 * k) - 1) / (2 * n)) 255 } 256 } 257 258 // Spherical Harmonics 259 sphericalHarmonic { |m, theta, phi| _SphericalHarmonic; ^this.primitiveFailed } 260 sphericalHarmonicR { |m, theta, phi| _SphericalHarmonicR; ^this.primitiveFailed } 261 sphericalHarmonicI { |m, theta, phi| _SphericalHarmonicI; ^this.primitiveFailed } 262 263 // Bessel Functions: 264 // First and second kind, zero finders, modified first and second kinds, 265 // spherical first and second kinds, derivatives 266 cylBesselJ { |x| _CylBesselJ; ^this.primitiveFailed } 267 cylNeumann { |x| _CylNeumann; ^this.primitiveFailed } 268 cylBesselJZero { |index| _CylBesselJZero; ^this.primitiveFailed } 269 cylNeumannZero { |index| _CylNeumannZero; ^this.primitiveFailed } 270 cylBesselI { |x| _CylBesselI; ^this.primitiveFailed } 271 cylBesselK { |x| _CylBesselK; ^this.primitiveFailed } 272 sphBessel { |x| _SphBessel; ^this.primitiveFailed } 273 sphNeumann { |x| _SphNeumann; ^this.primitiveFailed } 274 cylBesselJPrime { |x| _CylBesselJPrime; ^this.primitiveFailed } 275 cylNeumannPrime { |x| _CylNeumannPrime; ^this.primitiveFailed } 276 cylBesselIPrime { |x| _CylBesselIPrime; ^this.primitiveFailed } 277 cylBesselKPrime { |x| _CylBesselKPrime; ^this.primitiveFailed } 278 sphBesselPrime { |x| _SphBesselPrime; ^this.primitiveFailed } 279 sphNeumannPrime { |x| _SphNeumannPrime; ^this.primitiveFailed } 280 281 // Hankel Functions: 282 cylHankel1 { |x| _CylHankel1; ^this.primitiveFailed } 283 cylHankel2 { |x| _CylHankel2; ^this.primitiveFailed } 284 sphHankel1 { |x| _SphHankel1; ^this.primitiveFailed } 285 sphHankel2 { |x| _SphHankel2; ^this.primitiveFailed } 286 287 // Airy Functions: 288 airyAi { _AiryAi; ^this.primitiveFailed } 289 airyBi { _AiryBi; ^this.primitiveFailed } 290 airyAiPrime { _AiryAiPrime; ^this.primitiveFailed } 291 airyBiPrime { _AiryBiPrime; ^this.primitiveFailed } 292 airyAiZero { _AiryAiZero; ^this.primitiveFailed } 293 airyBiZero { _AiryBiZero; ^this.primitiveFailed } 294 295 // Elliptic Integrals: 296 // Carlson Form 297 ellintRf { |y, z| _EllintRf; ^this.primitiveFailed } 298 ellintRd { |y, z| _EllintRd; ^this.primitiveFailed } 299 ellintRj { |y, z, p| _EllintRj; ^this.primitiveFailed } 300 ellintRc { |y| _EllintRc; ^this.primitiveFailed } 301 ellintRg { |y, z| _EllintRg; ^this.primitiveFailed } 302 // Legendre Form - First, Second, Third Kind, D 303 ellint1 { |phi| _Ellint1; ^this.primitiveFailed } 304 ellint1C { _Ellint1C; ^this.primitiveFailed } 305 ellint2 { |phi| _Ellint2; ^this.primitiveFailed } 306 ellint2C { _Ellint2C; ^this.primitiveFailed } 307 ellint3 { |n, phi| _Ellint3; ^this.primitiveFailed } 308 ellint3C { |n| _Ellint3C; ^this.primitiveFailed } 309 ellintD { |phi| _EllintD; ^this.primitiveFailed } 310 ellintDC { _EllintDC; ^this.primitiveFailed } 311 // Jacobi Zeta, Heuman Lambda Functions 312 jacobiZeta { |phi| _JacobiZeta; ^this.primitiveFailed } 313 heumanLambda { |phi| _HeumanLambda; ^this.primitiveFailed } 314 315 // Jacobi Elliptic Functions: 316 jacobiCd { |u| _JacobiCd; ^this.primitiveFailed } 317 jacobiCn { |u| _JacobiCn; ^this.primitiveFailed } 318 jacobiCs { |u| _JacobiCs; ^this.primitiveFailed } 319 jacobiDc { |u| _JacobiDc; ^this.primitiveFailed } 320 jacobiDn { |u| _JacobiDn; ^this.primitiveFailed } 321 jacobiDs { |u| _JacobiDs; ^this.primitiveFailed } 322 jacobiNc { |u| _JacobiNc; ^this.primitiveFailed } 323 jacobiNd { |u| _JacobiNd; ^this.primitiveFailed } 324 jacobiNs { |u| _JacobiNs; ^this.primitiveFailed } 325 jacobiSc { |u| _JacobiSc; ^this.primitiveFailed } 326 jacobiSd { |u| _JacobiSd; ^this.primitiveFailed } 327 jacobiSn { |u| _JacobiSn; ^this.primitiveFailed } 328 329 // Riemann Zeta Function: 330 zeta { _Zeta; ^this.primitiveFailed } 331 332 // Exponential Integrals: 333 expintEn { |z| _ExpintEn; ^this.primitiveFailed } 334 expintEi { _ExpintEi; ^this.primitiveFailed } 335 336 // Basic Functions: 337 sinPi { _SinPi; ^this.primitiveFailed } 338 cosPi { _CosPi; ^this.primitiveFailed } 339 log1p { _Log1p; ^this.primitiveFailed } 340 expm1{ _ExpM1; ^this.primitiveFailed } 341 cbrt { _Cbrt; ^this.primitiveFailed } 342 sqrt1pm1 { _Sqrt1pm1; ^this.primitiveFailed } 343 powm1{ |y| _PowM1; ^this.primitiveFailed } 344 // hypot not needed... slightly slower than current implementation of hypot 345 346 // Sinus Cardinal ("sinc") and Hyperbolic Sinus Cardinal Functions: 347 sincPi { _SincPi; ^this.primitiveFailed } 348 sinhcPi { _SinhcPi; ^this.primitiveFailed } 349 350 // Inverse Hyperbolic Functions: 351 asinh { _Asinh; ^this.primitiveFailed } 352 acosh { _Acosh; ^this.primitiveFailed } 353 atanh { _Atanh; ^this.primitiveFailed } 354 355 // Owen's T function: 356 owensT { |a| _OwensT; ^this.primitiveFailed } 357 358 /* end Boost Special Functions */ 359 360 361 snap { |resolution = 1.0, margin = 0.05, strength = 1.0| 362 var round = round(this, resolution); 363 var diff = round - this; 364 ^if(abs(diff) < margin) { this + (strength * diff) } { this } 365 } 366 367 368 softRound { |resolution = 1.0, margin = 0.05, strength = 1.0| 369 var round = round(this, resolution); 370 var diff = round - this; 371 ^if(abs(diff) > margin) { this + (strength * diff) } { this } 372 } 373 374 linlin { |inMin, inMax, outMin, outMax, clip = \minmax| 375 // linear to linear mapping 376 switch(clip, 377 \minmax, { 378 if(this <= inMin) { ^outMin }; 379 if(this >= inMax) { ^outMax }; 380 }, 381 \min, { 382 if(this <= inMin) { ^outMin }; 383 }, 384 \max, { 385 if(this >= inMax) { ^outMax }; 386 } 387 ); 388 ^(this - inMin) / (inMax - inMin) * (outMax - outMin) + outMin 389 } 390 391 linexp { |inMin, inMax, outMin, outMax, clip=\minmax| 392 // linear to exponential mapping 393 switch(clip, 394 \minmax, { 395 if(this <= inMin) { ^outMin }; 396 if(this >= inMax) { ^outMax }; 397 }, 398 \min, { 399 if(this <= inMin) { ^outMin }; 400 }, 401 \max, { 402 if(this >= inMax) { ^outMax }; 403 } 404 ); 405 ^pow(outMax / outMin, (this - inMin) / (inMax - inMin)) * outMin 406 } 407 408 explin { |inMin, inMax, outMin, outMax, clip=\minmax| 409 // exponential to linear mapping 410 switch(clip, 411 \minmax, { 412 if(this <= inMin) { ^outMin }; 413 if(this >= inMax) { ^outMax }; 414 }, 415 \min, { 416 if(this <= inMin) { ^outMin }; 417 }, 418 \max, { 419 if(this >= inMax) { ^outMax }; 420 } 421 ); 422 ^(log(this / inMin)) / (log(inMax / inMin)) * (outMax - outMin) + outMin 423 } 424 425 expexp { |inMin, inMax, outMin, outMax, clip=\minmax| 426 // exponential to exponential mapping 427 switch(clip, 428 \minmax, { 429 if(this <= inMin) { ^outMin }; 430 if(this >= inMax) { ^outMax }; 431 }, 432 \min, { 433 if(this <= inMin) { ^outMin }; 434 }, 435 \max, { 436 if(this >= inMax) { ^outMax }; 437 } 438 ); 439 ^pow(outMax / outMin, log(this / inMin) / log(inMax / inMin)) * outMin 440 } 441 442 lincurve { |inMin = 0, inMax = 1, outMin = 0, outMax = 1, curve = -4, clip = \minmax| 443 var grow, a, b, scaled; 444 switch(clip, 445 \minmax, { 446 if(this <= inMin) { ^outMin }; 447 if(this >= inMax) { ^outMax }; 448 }, 449 \min, { 450 if(this <= inMin) { ^outMin }; 451 }, 452 \max, { 453 if(this >= inMax) { ^outMax }; 454 } 455 ); 456 if(abs(curve) < 0.001) { 457 // If the value should be clipped, it has already been clipped (above). 458 // If we got this far, then linlin does not need to do any clipping. 459 // Inlining the formula here makes it even faster. 460 ^(this - inMin) / (inMax - inMin) * (outMax - outMin) + outMin 461 }; 462 463 grow = exp(curve); 464 a = outMax - outMin / (1.0 - grow); 465 b = outMin + a; 466 scaled = (this - inMin) / (inMax - inMin); 467 468 ^b - (a * pow(grow, scaled)) 469 } 470 471 curvelin { |inMin = 0, inMax = 1, outMin = 0, outMax = 1, curve = -4, clip = \minmax| 472 var grow, a, b, scaled; 473 switch(clip, 474 \minmax, { 475 if(this <= inMin) { ^outMin }; 476 if(this >= inMax) { ^outMax }; 477 }, 478 \min, { 479 if(this <= inMin) { ^outMin }; 480 }, 481 \max, { 482 if(this >= inMax) { ^outMax }; 483 } 484 ); 485 if(abs(curve) < 0.001) { 486 // If the value should be clipped, it has already been clipped (above). 487 ^(this - inMin) / (inMax - inMin) * (outMax - outMin) + outMin 488 }; 489 490 grow = exp(curve); 491 a = inMax - inMin / (1.0 - grow); 492 b = inMin + a; 493 494 ^log((b - this) / a) * (outMax - outMin) / curve + outMin 495 } 496 497 bilin { |inCenter, inMin, inMax, outCenter, outMin, outMax, clip=\minmax| 498 // triangular linear mapping 499 switch(clip, 500 \minmax, { 501 if(this <= inMin) { ^outMin }; 502 if(this >= inMax) { ^outMax }; 503 }, 504 \min, { 505 if(this <= inMin) { ^outMin }; 506 }, 507 \max, { 508 if(this >= inMax) { ^outMax }; 509 } 510 ); 511 ^if(this >= inCenter) { 512 this.linlin(inCenter, inMax, outCenter, outMax, \none) 513 } { 514 this.linlin(inMin, inCenter, outMin, outCenter, \none) 515 } 516 } 517 518 biexp { |inCenter, inMin, inMax, outCenter, outMin, outMax, clip=\minmax| 519 // triangular exponential mapping 520 switch(clip, 521 \minmax, { 522 if(this <= inMin) { ^outMin }; 523 if(this >= inMax) { ^outMax }; 524 }, 525 \min, { 526 if(this <= inMin) { ^outMin }; 527 }, 528 \max, { 529 if(this >= inMax) { ^outMax }; 530 } 531 ); 532 ^if(this >= inCenter) { 533 this.explin(inCenter, inMax, outCenter, outMax, \none) 534 } { 535 this.explin(inMin, inCenter, outMin, outCenter, \none) 536 } 537 } 538 539 moddif { |aNumber = 0.0, mod = 1.0| 540 var diff = absdif(this, aNumber) % mod; 541 var modhalf = mod * 0.5; 542 ^modhalf - absdif(diff, modhalf) 543 } 544 545 lcurve { |a = 1.0, m = 0.0, n = 1.0, tau = 1.0| 546 var rTau, x = this.neg; 547 ^if(tau == 1.0) { 548 a * (m * exp(x) + 1) / (n * exp(x) + 1) 549 } { 550 rTau = tau.reciprocal; 551 a * (m * exp(x) * rTau + 1) / (n * exp(x) * rTau + 1) 552 } 553 } 554 gauss { |standardDeviation| 555 ^(((sqrt(-2 * log(1.0.rand)) * sin(2pi.rand)) * standardDeviation) + this) 556 } 557 gaussCurve { |a = 1.0, b = 0.0, c = 1.0| 558 ^a * (exp(squared(this - b) / (-2.0 * squared(c)))) 559 } 560 561 asPoint { 562 ^Point.new(this, this) 563 } 564 565 asWarp { |spec| 566 ^CurveWarp.new(spec, this) 567 } 568 569 // scheduled Routine support 570 wait { ^this.yield } 571 waitUntil { ^(this - thisThread.beats).max(0).yield } 572 sleep { 573 var thread = thisThread; 574 thread.clock.sched(this, { thread.next; nil }); 575 nil.yield; 576 } 577 578 printOn { |stream| 579 stream.putAll(this.asString); 580 } 581 storeOn { |stream| 582 stream.putAll(this.asString); 583 } 584 585 586 rate { ^'scalar' } // scalarRate constant 587 asAudioRateInput { ^if(this == 0) { Silent.ar } { DC.ar(this) } } 588 589 madd { |mul, add| 590 ^(this * mul) + add 591 } 592 593 lag { ^this } 594 lag2 { ^this } 595 lag3 { ^this } 596 lagud { ^this } 597 lag2ud { ^this } 598 lag3ud { ^this } 599 varlag { ^this } 600 slew { ^this } 601 602 poll { |trig = 10, label, trigid = -1| 603 ^Poll(trig, this, label, trigid) 604 } 605 606 // support for writing synth defs 607 writeInputSpec { |file, synth| 608 var constIndex = synth.constants.at(this.asFloat); 609 if(constIndex.isNil) { 610 Error("SimpleNumber-writeInputSpec constant not found: " ++ this.asFloat).throw; 611 }; 612 file.putInt32(-1); 613 file.putInt32(constIndex); 614 } 615 616 series { |second, last| 617 _SimpleNumberSeries 618 ^this.primitiveFailed 619 /* var step, size; 620 second = second ?? { if(this < last) { this + 1 } { this - 1 } }; 621 step = second - this; 622 size = floor((last - this) / step + 0.001).asInteger + 1; 623 ^Array.series(size, this, step) */ 624 } 625 626 seriesIter { |second, last| 627 var step, size; 628 629 if(second.isNil) { 630 last = last ? inf; 631 step = if(this < last, 1, -1); 632 }{ 633 last ?? { last = if(second < this, -inf, inf) }; 634 step = second - this; 635 }; 636 637 ^if(step < 0) { 638 r { 639 var val = this; 640 while { 641 val >= last; 642 } { 643 val.yield; 644 val = val + step; 645 }; 646 } 647 } { 648 r { 649 var val = this; 650 while { 651 val <= last; 652 } { 653 val.yield; 654 val = val + step; 655 } 656 } 657 } 658 } 659 660 661 degreeToKey { |scale, stepsPerOctave = 12| 662 var scaleDegree = this.round.asInteger; 663 var accidental = (this - scaleDegree) * 10.0; 664 ^scale.performDegreeToKey(scaleDegree, stepsPerOctave, accidental) 665 } 666 667 keyToDegree { |scale, stepsPerOctave = 12| 668 ^scale.performKeyToDegree(this, stepsPerOctave) 669 } 670 671 nearestInList { |list| // collection is sorted 672 ^list.performNearestInList(this); 673 } 674 675 nearestInScale { |scale, stepsPerOctave = 12| // collection is sorted 676 ^scale.performNearestInScale(this, stepsPerOctave); 677 } 678 679 partition { |parts = 2, min = 1| 680 // randomly partition a number into parts of at least min size : 681 var n = this - (min - 1 * parts); 682 ^(1..n-1).scramble.keep(parts-1).sort.add(n).differentiate + (min - 1) 683 } 684 685 nextTimeOnGrid { |clock| 686 ^clock.nextTimeOnGrid(this, 0) 687 } 688 689 playAndDelta {} 690 691 asQuant { ^Quant(this) } 692 693 // a clock format inspired by ISO 8601 time interval display (truncated representation) 694 // receiver is a time in seconds, returns string "ddd:hh:mm:ss.sss" 695 // see String:asSecs for complement 696 697 asTimeString { |precision = 0.001, maxDays = 365, dropDaysIfPossible = true| 698 var number, decimal, days, hours, minutes, seconds, mseconds; 699 700 // min value of precision is 0.001; this ensures that we stick to 3 decimal places in the 701 // formatted string. 702 precision = max(precision, 0.001); 703 704 number = this.round(precision); 705 decimal = number.asInteger; 706 days = decimal.div(86400).min(maxDays); 707 days = if(dropDaysIfPossible and: { days == 0 }) { 708 days = "" 709 } { 710 days.asString.padLeft(3, "0").add($:); 711 }; 712 hours = (decimal.div(3600) % 24).asString.padLeft(2, "0").add($:); 713 minutes = (decimal.div(60) % 60).asString.padLeft(2, "0").add($:); 714 seconds = (decimal % 60).asString.padLeft(2, "0").add($.); 715 mseconds = number.frac * 1000; 716 mseconds = mseconds.round.asInteger.asString.padLeft(3, "0"); 717 ^days ++ hours ++ minutes ++ seconds ++ mseconds 718 } 719 720 asFraction { |denominator = 100, fasterBetter = true| 721 _AsFraction 722 // asFraction will return a fraction that is the best approximation up to the given 723 // denominator. 724 // if fasterBetter is true it may find a much closer approximation and do it faster. 725 ^this.primitiveFailed 726 } 727 728 prSimpleNumberSeries { | second, last | 729 _SimpleNumberSeries 730 ^this.primitiveFailed 731 } 732 733 asBufWithValues { 734 ^this 735 } 736 737 // this method could be refactored by dispatching, but we're trying to keep the overhead low. 738 739 schedBundleArrayOnClock { |clock, bundleArray, lag = 0, server, latency| 740 var sendBundle = { server.sendBundle(latency ? server.latency, *bundleArray) }; 741 // "this" is the delta time for the clock (usually in beats) 742 // "lag" is a tempo independent absolute lag time (in seconds) 743 if (lag != 0) { 744 if(this != 0) { 745 // schedule on both clocks 746 clock.sched(this, { SystemClock.sched(lag, sendBundle) }) 747 } { 748 // only lag specified: schedule only on the system clock 749 SystemClock.sched(lag, sendBundle) 750 } 751 } { 752 if(this != 0) { 753 // only delta specified: schedule only on the clock passed in 754 clock.sched(this, sendBundle) 755 } { 756 // no delays: send directly 757 sendBundle.value 758 } 759 } 760 761 } 762} 763