⌈⌋ ⎇ branch:  Bitrhythm


Artifact Content

Artifact d3b0ef05713a22ee3a0c8f4dc93223c217974d668d3a1bf78c02ac552d25aabd:


'use strict';

/**
 * Limit a number to within a minimum and maximum
 * @param  {number} value Input value
 * @param  {number} min   Lower limit
 * @param  {number} max   Upper limit
 * @return {number}       The input value constrained within the lower and upper limits
 * @example
 * Nexus.clip(11,0,10)   // returns 10
 * Nexus.clip(-1,0,10)   // returns 0
 * Nexus.clip(5,0,10)    // returns 5
 */

exports.clip = (value,min,max) => {
  return Math.min(Math.max(value,min),max);
};

exports.normalize = (value,min,max) => {
  return ( (value-min) / (max-min) );
};

/**
 * Scale a value from one range to another range.
 * @param  {number} inNum  Input value
 * @param  {number} inMin  Input range minimum
 * @param  {number} inMax  Input range maximum
 * @param  {number} outMin Output range minimum
 * @param  {number} outMax Output range maximum
 * @return {number}        The input value scaled to its new range
 * @example
 * Nexus.scale(0.5,0,1,0,10)   // returns 5
 * Nexus.scale(0.9,0,1,1,0)    // returns 0.1
 */
exports.scale = (inNum, inMin, inMax, outMin, outMax) => {
  if (inMin === inMax) {
    return outMin;
  }
  return (((inNum - inMin) * (outMax - outMin)) / (inMax - inMin)) + outMin;
};

exports.toPolar = (x,y) => {
  var r = Math.sqrt(x*x + y*y);

  var theta = Math.atan2(y,x);
  if (theta < 0) {
    theta = theta + (2 * Math.PI);
  }
  return {radius: r, angle: theta};
};

exports.toCartesian = function(radius, angle){
  var cos = Math.cos(angle);
  var sin = Math.sin(angle);
  return {x: radius*cos, y: radius*sin*-1};
};
/*
exports.polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}  */



exports.prune = function(data, scale) {
  return parseFloat(data.toFixed(scale));
};

exports.invert = function (inNum) {
  return exports.scale(inNum, 1, 0, 0, 1);
};

/**
 * Convert a MIDi note number to a frequency value in equal temperament.
 * @param  {number} midi MIDI note value
 * @return {number}      Frequence value
 * @example
 * Nexus.mtof(60)  // returns the frequency number of Middle C
 */
exports.mtof = function(midi) {
  return Math.pow(2, ((midi-69)/12)) * 440;
};

/**
 * Interpolate between two numbers
 * @param  {number} loc Interpolation index (0-1)
 * @param  {number} min Lower value
 * @param  {number} max Upper value
 * @return {number}     Interpolated value
 * @example
 * Nexus.interp(0.5,2,4)   // returns 3
 * Nexus.interp(0.1,0,10)     // returns 1
 */
exports.interp = function(loc,min,max) {
  return loc * (max - min) + min;
};

/**
 * Return a random choice from a list of arguments
 * @return {various} One random argument
 * @example
 * Nexus.pick(1,2,3,4)   // returns 1, 2, 3, or 4
 * Nexus.pick(function1,function2)   // returns either function1 or function2
 */
exports.pick = function() {
  return arguments[~~(Math.random()*arguments.length)];
};

/**
 * Returns an octave multiplier for frequency values
 * @param  {number} num Relative octave number (e.g. -1 for one octave down, 1 for one octave up)
 * @return {number}     Octave multiplier
 * @example
 * Nexus.octave(-1)  // returns 0.5
 * Nexus.octave(0)   // returns 1
 * Nexus.octave(1)   // returns 2
 * Nexus.octave(2)   // returns 4
 */
exports.octave = function(num) {
  return Math.pow(2,num);
};

/**
 * Random integer generator. If no second argument is given, will return random integer from 0 to bound1.
 * @param  {number} bound1 Minimum random value
 * @param  {number} bound2 Maximum random value
 * @return {number}        Random integer between lower and upper boundary
 * @example
 * Nexus.ri(10)    // returns random int from 0 to 10
 * Nexus.ri(20,2000) // returns random int from 20 to 2000
 */
exports.ri = function(bound1,bound2) {
  if (!bound2) {
    bound2 = bound1;
    bound1 = 0;
  }
  var low = Math.min(bound1,bound2);
  var high = Math.max(bound1,bound2);
  return Math.floor(Math.random()*(high-low)+low);
};

/**
 * Random float number generator. If no second argument is given, will return random float from 0 to bound1.
 * @param  {number} bound1 Minimum random value
 * @param  {number} bound2 Maximum random value
 * @return {number}        Random float between lower and upper boundary
 * @example
 * Nexus.rf(1)    // returns random float from 0 to 1
 * Nexus.rf(1,2) // returns random float from 1 to 2
 */
exports.rf = function(bound1,bound2) {
  if (!bound2) {
    bound2 = bound1;
    bound1 = 0;
  }
  var low = Math.min(bound1,bound2);
  var high = Math.max(bound1,bound2);
  return Math.random()*(high-low)+low;
};


exports.cycle = function(input,min,max) {
  input++;
  if (input >= max) {
    input = min;
  }
  return input;
};

/**
 * Average an array of numbers
 * @param  {Array} data Array of numbers to average
 * @return {number}      Average of the input data
 * @example
 * Nexus.average([0,2,4,6,8,10])   // returns 5
 */
exports.average = function(data) {
  let total = 0;
  for (var i=0;i<data.length;i++) {
    total += data[i];
  }
  return total / data.length;
};

/**
 * Get the distance from one (x,y) point to another (x,y) point
 * @param  {number} x1 x of first point
 * @param  {number} y1 y of first point
 * @param  {number} x2 x of second point
 * @param  {number} y2 y of second poiny
 * @return {number}    Distance
 * @example
 * Nexus.distance(0,0,3,4)   // returns 5
 */
exports.distance = function(x1,y1,x2,y2) {
  let a = x1 - x2;
  let b = y1 - y2;
  return Math.sqrt( a*a + b*b );
};

exports.gainToDB = function(gain) {
  return 20 * Math.log10(gain);
};

/**
 * Flip a coin, returning either 0 or 1 according to a probability
 * @param  {number} [odds=0.5] Likelihood of returning 1
 * @return {number}            1 or 0
 * @example
 * Nexus.coin(0.1)   // returns 1 (10% of the time) or 0 (90% of the time)
 */
exports.coin = function(odds=0.5) {
  if (exports.rf(0,1) < odds) {
    return 1;
  } else {
    return 0;
  }
};