Tone.js/Tone/effect/Chebyshev.js

138 lines
3.3 KiB
JavaScript
Raw Normal View History

import Tone from "../core/Tone";
import "../effect/Effect";
import "../signal/WaveShaper";
/**
* @class Tone.ChebyShev is a Chebyshev waveshaper, an effect which is good
* for making different types of distortion sounds.
* Note that odd orders sound very different from even ones,
* and order = 1 is no change.
* Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php).
*
* @extends {Tone.Effect}
* @constructor
* @param {Positive|Object} [order] The order of the chebyshev polynomial. Normal range between 1-100.
* @example
* //create a new cheby
* var cheby = new Tone.Chebyshev(50);
* //create a monosynth connected to our cheby
* synth = new Tone.MonoSynth().connect(cheby);
*/
Tone.Chebyshev = function(){
var options = Tone.defaults(arguments, ["order"], Tone.Chebyshev);
Tone.Effect.call(this, options);
/**
* @type {WaveShaperNode}
* @private
*/
this._shaper = new Tone.WaveShaper(4096);
/**
* holds onto the order of the filter
* @type {number}
* @private
*/
this._order = options.order;
2015-01-20 13:55:28 +00:00
this.connectEffect(this._shaper);
this.order = options.order;
this.oversample = options.oversample;
};
Tone.extend(Tone.Chebyshev, Tone.Effect);
/**
* @static
* @const
* @type {Object}
*/
Tone.Chebyshev.defaults = {
"order" : 1,
"oversample" : "none"
};
/**
* get the coefficient for that degree
* @param {number} x the x value
* @param {number} degree
* @param {Object} memo memoize the computed value.
* this speeds up computation greatly.
* @return {number} the coefficient
* @private
*/
Tone.Chebyshev.prototype._getCoefficient = function(x, degree, memo){
if (memo.hasOwnProperty(degree)){
return memo[degree];
} else if (degree === 0){
memo[degree] = 0;
} else if (degree === 1){
memo[degree] = x;
} else {
memo[degree] = 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo);
}
return memo[degree];
};
/**
* The order of the Chebyshev polynomial which creates
* the equation which is applied to the incoming
* signal through a Tone.WaveShaper. The equations
* are in the form:<br>
* order 2: 2x^2 + 1<br>
* order 3: 4x^3 + 3x <br>
* @memberOf Tone.Chebyshev#
* @type {Positive}
* @name order
*/
Object.defineProperty(Tone.Chebyshev.prototype, "order", {
get : function(){
return this._order;
},
set : function(order){
this._order = order;
var curve = new Array(4096);
var len = curve.length;
for (var i = 0; i < len; ++i){
var x = i * 2 / len - 1;
if (x === 0){
//should output 0 when input is 0
curve[i] = 0;
} else {
curve[i] = this._getCoefficient(x, order, {});
2015-02-10 16:40:27 +00:00
}
}
this._shaper.curve = curve;
}
});
2015-02-10 16:40:27 +00:00
/**
* The oversampling of the effect. Can either be "none", "2x" or "4x".
* @memberOf Tone.Chebyshev#
* @type {string}
* @name oversample
*/
Object.defineProperty(Tone.Chebyshev.prototype, "oversample", {
get : function(){
return this._shaper.oversample;
},
set : function(oversampling){
this._shaper.oversample = oversampling;
}
});
2015-02-10 16:40:27 +00:00
/**
* Clean up.
* @returns {Tone.Chebyshev} this
*/
Tone.Chebyshev.prototype.dispose = function(){
Tone.Effect.prototype.dispose.call(this);
this._shaper.dispose();
this._shaper = null;
return this;
};
export default Tone.Chebyshev;