Tone.js/Tone/component/Envelope.js

229 lines
6 KiB
JavaScript
Raw Normal View History

define(["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){
2014-03-11 23:27:46 +00:00
2014-06-15 23:35:00 +00:00
/**
2014-06-16 23:59:58 +00:00
* Envelope
2014-06-20 05:23:35 +00:00
* ADR envelope generator attaches to an AudioParam or AudioNode
2014-06-16 23:59:58 +00:00
*
* @constructor
* @extends {Tone}
* @param {Tone.Time|Object=} attack
2014-06-16 23:59:58 +00:00
* @param {Tone.Time=} decay
* @param {number=} sustain a percentage (0-1) of the full amplitude
* @param {Tone.Time=} release
2014-06-15 23:35:00 +00:00
*/
Tone.Envelope = function(){
//get all of the defaults
var options = this.optionsObject(arguments, ["attack", "decay", "sustain", "release"], Tone.Envelope._defaults);
2014-08-24 16:12:40 +00:00
/**
* the output
* @type {GainNode}
*/
this.output = this.context.createGain();
2014-03-26 19:38:21 +00:00
/**
* the attack time in seconds
* @type {number}
*/
2014-08-24 16:12:40 +00:00
this.attack = this.toSeconds(options.attack);
/**
* the decay time in seconds
* @type {number}
*/
2014-08-24 16:12:40 +00:00
this.decay = this.toSeconds(options.decay);
/**
* the sustain is a value between 0-1
* @type {number}
*/
2014-08-24 16:12:40 +00:00
this.sustain = this.toSeconds(options.sustain);
/**
* the release time in seconds
* @type {number}
*/
2014-08-24 16:12:40 +00:00
this.release = this.toSeconds(options.release);
/**
* the minimum output of the envelope
* @type {number}
*/
2014-08-24 16:12:40 +00:00
this.min = this.toSeconds(options.min);
/**
* the maximum output of the envelope
* @type {number}
*/
2014-08-24 16:12:40 +00:00
this.max = this.toSeconds(options.max);
2014-04-06 00:47:59 +00:00
/**
* the control signal
* @type {Tone.Signal}
* @private
*/
this._control = new Tone.Signal(this.min);
//connections
this._control.connect(this.output);
2014-06-15 21:37:55 +00:00
};
2014-03-11 23:27:46 +00:00
2014-06-15 21:37:55 +00:00
Tone.extend(Tone.Envelope);
2014-04-06 00:47:59 +00:00
/**
* the default parameters
*
* @static
* @private
*/
Tone.Envelope._defaults = {
"attack" : 0.01,
"decay" : 0.1,
"sustain" : 0.5,
"release" : 1,
"min" : 0,
"max" : 1
};
2014-08-24 16:12:40 +00:00
// SETTERS //
/**
* set all of the parameters in bulk
* @param {Object} param the name of member as the key
* and the value as the value
*/
Tone.Envelope.prototype.set = function(params){
2014-08-24 16:12:40 +00:00
if (!this.isUndef(params.attack)) this.setAttack(params.attack);
if (!this.isUndef(params.decay)) this.setDecay(params.decay);
if (!this.isUndef(params.sustain)) this.setSustain(params.sustain);
if (!this.isUndef(params.release)) this.setRelease(params.release);
if (!this.isUndef(params.min)) this.min = params.min;
if (!this.isUndef(params.max)) this.max = params.max;
};
2014-08-24 16:12:40 +00:00
/**
* set the attack time
* @param {Tone.Time} time
*/
Tone.Envelope.prototype.setAttack = function(time){
this.attack = this.toSeconds(time);
};
/**
* set the decay time
* @param {Tone.Time} time
*/
Tone.Envelope.prototype.setDecay = function(time){
this.decay = this.toSeconds(time);
};
/**
* set the release time
* @param {Tone.Time} time
*/
Tone.Envelope.prototype.setRelease = function(time){
this.release = this.toSeconds(time);
};
/**
* set the sustain amount
* @param {number} sustain value between 0-1
*/
Tone.Envelope.prototype.setSustain = function(sustain){
this.sustain = sustain;
};
2014-06-15 23:35:00 +00:00
/**
* attack->decay->sustain linear ramp
2014-06-21 17:06:12 +00:00
* @param {Tone.Time=} time
2014-06-15 23:35:00 +00:00
*/
2014-04-06 00:47:59 +00:00
Tone.Envelope.prototype.triggerAttack = function(time){
2014-06-21 17:06:12 +00:00
var sustainVal = (this.max - this.min) * this.sustain + this.min;
2014-04-06 00:47:59 +00:00
if (!time){
this._control.linearRampToValueNow(this.max, this.attack);
this._control.linearRampToValueAtTime(sustainVal, this.now() + this.attack + this.decay);
2014-06-21 17:06:12 +00:00
} else {
var startVal = this.min;
time = this.toSeconds(time);
this._control.cancelScheduledValues(time);
this._control.setValueAtTime(startVal, time);
this._control.linearRampToValueAtTime(this.max, time + this.attack);
this._control.linearRampToValueAtTime(sustainVal, time + this.attack + this.decay);
2014-04-06 00:47:59 +00:00
}
2014-06-15 21:37:55 +00:00
};
2014-04-06 00:47:59 +00:00
2014-06-15 23:35:00 +00:00
/**
2014-06-21 17:06:12 +00:00
* attack->decay->sustain exponential attack and linear decay
* @param {Tone.Time=} time
2014-06-15 23:35:00 +00:00
*/
2014-06-20 05:23:35 +00:00
Tone.Envelope.prototype.triggerExponentialAttack = function(time){
2014-06-21 17:06:12 +00:00
var sustainVal = (this.max - this.min) * this.sustain + this.min;
2014-04-06 00:47:59 +00:00
if (!time){
this._control.exponentialRampToValueNow(this.max, this.attack);
this._control.linearRampToValueAtTime(sustainVal, this.now() + this.attack + this.decay);
2014-06-21 17:06:12 +00:00
} else {
var startVal = this.min;
time = this.toSeconds(time);
this._control.cancelScheduledValues(time);
this._control.setValueAtTime(startVal, time);
this._control.exponentialRampToValueAtTime(this.max, time + this.attack);
this._control.linearRampToValueAtTime(sustainVal, time + this.attack + this.decay);
2014-04-06 00:47:59 +00:00
}
2014-06-15 21:37:55 +00:00
};
2014-06-15 23:35:00 +00:00
/**
* triggers the release of the envelope with a linear ramp
2014-06-21 17:06:12 +00:00
* @param {Tone.Time=} time
2014-06-15 23:35:00 +00:00
*/
2014-04-06 00:47:59 +00:00
Tone.Envelope.prototype.triggerRelease = function(time){
if (time){
2014-06-21 17:06:12 +00:00
//if there's a time, start at the sustain value
2014-07-22 16:48:22 +00:00
var startVal = (this.max - this.min) * this.sustain + this.min;
2014-06-21 17:06:12 +00:00
time = this.toSeconds(time);
this._control.cancelScheduledValues(time);
this._control.setValueAtTime(startVal, time);
this._control.linearRampToValueAtTime(this.min, time + this.toSeconds(this.release));
2014-06-21 17:06:12 +00:00
} else {
this._control.linearRampToValueNow(this.min, this.toSeconds(this.release));
2014-04-06 00:47:59 +00:00
}
2014-06-15 21:37:55 +00:00
};
2014-03-11 23:27:46 +00:00
2014-06-15 23:35:00 +00:00
/**
* triggers the release of the envelope with an exponential ramp
2014-06-16 23:59:58 +00:00
*
2014-06-21 17:06:12 +00:00
* @param {Tone.Time=} time
2014-06-15 23:35:00 +00:00
*/
2014-06-20 05:23:35 +00:00
Tone.Envelope.prototype.triggerExponentialRelease = function(time){
2014-04-06 00:47:59 +00:00
if (time){
2014-06-21 17:06:12 +00:00
//if there's a time, start at the sustain value
2014-07-22 16:48:22 +00:00
var startVal = (this.max - this.min) * this.sustain + this.min;
2014-06-21 17:06:12 +00:00
time = this.toSeconds(time);
this._control.cancelScheduledValues(time);
this._control.setValueAtTime(startVal, time);
this._control.exponentialRampToValueAtTime(this.min, time + this.toSeconds(this.release));
2014-06-21 17:06:12 +00:00
} else {
this._control.exponentialRampToValueNow(this.min, this.toSeconds(this.release));
2014-04-06 00:47:59 +00:00
}
2014-06-15 21:37:55 +00:00
};
2014-06-15 23:35:00 +00:00
/**
* borrows the connect method from {@link Tone.Signal}
*
* @function
2014-06-15 23:35:00 +00:00
*/
Tone.Envelope.prototype.connect = Tone.Signal.prototype.connect;
2014-04-06 00:47:59 +00:00
2014-06-20 05:23:35 +00:00
/**
* disconnect and dispose
*/
Tone.Envelope.prototype.dispose = function(){
Tone.prototype.dispose.call(this);
this._control.dispose();
this._control = null;
2014-06-20 05:23:35 +00:00
};
2014-04-06 00:47:59 +00:00
return Tone.Envelope;
});