Tone.js/Tone/control/CtrlInterpolate.js

132 lines
3.2 KiB
JavaScript
Raw Normal View History

import Tone from "../core/Tone";
import "../type/Type";
/**
* @class Tone.CtrlInterpolate will interpolate between given values based
* on the "index" property. Passing in an array or object literal
* will interpolate each of the parameters. Note (i.e. "C3")
* and Time (i.e. "4n + 2") can be interpolated. All other values are
* assumed to be numbers.
* @example
* var interp = new Tone.CtrlInterpolate([0, 2, 9, 4]);
* interp.index = 0.75;
* interp.value; //returns 1.5
*
* @example
* var interp = new Tone.CtrlInterpolate([
* [2, 4, 5],
* [9, 3, 2],
* ]);
* @param {Array} values The array of values to interpolate over
* @param {Positive} index The initial interpolation index.
* @extends {Tone}
*/
Tone.CtrlInterpolate = function(){
var options = Tone.defaults(arguments, ["values", "index"], Tone.CtrlInterpolate);
Tone.call(this);
/**
* The values to interpolate between
* @type {Array}
*/
this.values = options.values;
/**
* The interpolated index between values. For example: a value of 1.5
* would interpolate equally between the value at index 1
* and the value at index 2.
* @example
* interp.index = 0;
* interp.value; //returns the value at 0
* interp.index = 0.5;
* interp.value; //returns the value between indices 0 and 1.
* @type {Positive}
*/
this.index = options.index;
};
Tone.extend(Tone.CtrlInterpolate);
/**
* The defaults
* @const
* @type {Object}
*/
Tone.CtrlInterpolate.defaults = {
"index" : 0,
"values" : []
};
/**
* The current interpolated value based on the index
* @readOnly
* @memberOf Tone.CtrlInterpolate#
* @type {*}
* @name value
*/
Object.defineProperty(Tone.CtrlInterpolate.prototype, "value", {
get : function(){
var index = this.index;
index = Math.min(index, this.values.length - 1);
var lowerPosition = Math.floor(index);
var lower = this.values[lowerPosition];
var upper = this.values[Math.ceil(index)];
return this._interpolate(index - lowerPosition, lower, upper);
}
});
/**
* Internal interpolation routine
* @param {NormalRange} index The index between the lower and upper
* @param {*} lower
* @param {*} upper
* @return {*} The interpolated value
* @private
*/
Tone.CtrlInterpolate.prototype._interpolate = function(index, lower, upper){
if (Tone.isArray(lower)){
var retArray = [];
for (var i = 0; i < lower.length; i++){
retArray[i] = this._interpolate(index, lower[i], upper[i]);
}
return retArray;
} else if (Tone.isObject(lower)){
var retObj = {};
for (var attr in lower){
retObj[attr] = this._interpolate(index, lower[attr], upper[attr]);
}
return retObj;
} else {
lower = this._toNumber(lower);
upper = this._toNumber(upper);
return (1 - index) * lower + index * upper;
}
};
/**
* Convert from the given type into a number
* @param {Number|String} value
* @return {Number}
* @private
*/
Tone.CtrlInterpolate.prototype._toNumber = function(val){
if (Tone.isNumber(val)){
return val;
} else {
//otherwise assume that it's Time...
return this.toSeconds(val);
}
};
/**
* Clean up
* @return {Tone.CtrlInterpolate} this
*/
Tone.CtrlInterpolate.prototype.dispose = function(){
this.values = null;
};
export default Tone.CtrlInterpolate;