2014-04-11 23:17:01 +00:00
|
|
|
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=} attack
|
|
|
|
* @param {Tone.Time=} decay
|
|
|
|
* @param {number=} sustain a percentage (0-1) of the full amplitude
|
|
|
|
* @param {Tone.Time=} release
|
|
|
|
* @param {number=} minOutput the lowest point of the envelope
|
|
|
|
* @param {number=} maxOutput the highest point of the envelope
|
2014-06-15 23:35:00 +00:00
|
|
|
*/
|
2014-04-11 23:17:01 +00:00
|
|
|
Tone.Envelope = function(attack, decay, sustain, release, minOutput, maxOutput){
|
2014-04-06 00:47:59 +00:00
|
|
|
//extend Unit
|
|
|
|
Tone.call(this);
|
2014-03-26 19:38:21 +00:00
|
|
|
|
2014-06-20 05:23:35 +00:00
|
|
|
/** @type {number} */
|
2014-06-15 21:37:55 +00:00
|
|
|
this.attack = this.defaultArg(attack, 0.01);
|
2014-06-20 05:23:35 +00:00
|
|
|
/** @type {number} */
|
2014-06-15 21:37:55 +00:00
|
|
|
this.decay = this.defaultArg(decay, 0.1);
|
2014-06-20 05:23:35 +00:00
|
|
|
/** @type {number} */
|
2014-04-06 00:47:59 +00:00
|
|
|
this.release = this.defaultArg(release, 1);
|
2014-06-20 05:23:35 +00:00
|
|
|
/** @type {number} */
|
2014-06-15 21:37:55 +00:00
|
|
|
this.sustain = this.defaultArg(sustain, 0.5);
|
2014-03-11 23:27:46 +00:00
|
|
|
|
2014-06-20 05:23:35 +00:00
|
|
|
/** @type {number} */
|
2014-04-06 00:47:59 +00:00
|
|
|
this.min = this.defaultArg(minOutput, 0);
|
2014-06-20 05:23:35 +00:00
|
|
|
/** @type {number} */
|
2014-04-06 00:47:59 +00:00
|
|
|
this.max = this.defaultArg(maxOutput, 1);
|
|
|
|
|
2014-06-20 05:23:35 +00:00
|
|
|
/** @type {Tone.Signal} */
|
2014-04-11 23:17:01 +00:00
|
|
|
this.control = new Tone.Signal(this.min);
|
|
|
|
|
|
|
|
//connections
|
|
|
|
this.chain(this.control, 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
|
|
|
|
2014-06-15 23:35:00 +00:00
|
|
|
/**
|
|
|
|
* attack->decay->sustain linear ramp
|
|
|
|
* @param {Tone.Time} time
|
|
|
|
*/
|
2014-04-06 00:47:59 +00:00
|
|
|
Tone.Envelope.prototype.triggerAttack = function(time){
|
|
|
|
var startVal = this.min;
|
|
|
|
if (!time){
|
2014-04-11 23:17:01 +00:00
|
|
|
startVal = this.control.getValue();
|
2014-04-06 00:47:59 +00:00
|
|
|
}
|
|
|
|
time = this.defaultArg(time, this.now());
|
2014-04-11 23:17:01 +00:00
|
|
|
time = this.toSeconds(time);
|
|
|
|
this.control.cancelScheduledValues(time);
|
|
|
|
this.control.setValueAtTime(startVal, time);
|
|
|
|
var attackTime = this.toSeconds(this.attack);
|
|
|
|
var decayTime = this.toSeconds(this.decay);
|
|
|
|
this.control.linearRampToValueAtTime(this.max, time + attackTime);
|
2014-04-06 00:47:59 +00:00
|
|
|
var sustainVal = (this.max - this.min) * this.sustain + this.min;
|
2014-04-11 23:17:01 +00:00
|
|
|
this.control.linearRampToValueAtTime(sustainVal, time + attackTime + decayTime);
|
2014-06-15 21:37:55 +00:00
|
|
|
};
|
2014-04-06 00:47:59 +00:00
|
|
|
|
2014-06-15 23:35:00 +00:00
|
|
|
/**
|
|
|
|
* attack->decay->sustain exponential ramp
|
|
|
|
* @param {Tone.Time} time
|
|
|
|
*/
|
2014-06-20 05:23:35 +00:00
|
|
|
Tone.Envelope.prototype.triggerExponentialAttack = function(time){
|
2014-04-06 00:47:59 +00:00
|
|
|
var startVal = this.min;
|
|
|
|
if (!time){
|
2014-04-11 23:17:01 +00:00
|
|
|
startVal = this.control.getValue();
|
2014-04-06 00:47:59 +00:00
|
|
|
}
|
2014-04-11 23:17:01 +00:00
|
|
|
time = this.toSeconds(time);
|
|
|
|
this.control.cancelScheduledValues(time);
|
|
|
|
this.control.setValueAtTime(startVal, time);
|
|
|
|
var attackTime = this.toSeconds(this.attack);
|
|
|
|
var decayTime = this.toSeconds(this.decay);
|
|
|
|
this.control.linearRampToValueAtTime(this.max, time + attackTime);
|
2014-04-06 00:47:59 +00:00
|
|
|
var sustainVal = (this.max - this.min) * this.sustain + this.min;
|
2014-04-11 23:17:01 +00:00
|
|
|
this.control.exponentialRampToValueAtTime(sustainVal, time + attackTime + decayTime);
|
2014-06-15 21:37:55 +00:00
|
|
|
};
|
2014-03-24 17:41:08 +00:00
|
|
|
|
2014-06-15 23:35:00 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* triggers the release of the envelope with a linear ramp
|
|
|
|
* @param {Tone.Time} time
|
|
|
|
*/
|
2014-04-06 00:47:59 +00:00
|
|
|
Tone.Envelope.prototype.triggerRelease = function(time){
|
2014-04-11 23:17:01 +00:00
|
|
|
var startVal = this.control.getValue();
|
2014-04-06 00:47:59 +00:00
|
|
|
if (time){
|
|
|
|
startVal = (this.max - this.min) * this.sustain + this.min;
|
|
|
|
}
|
2014-04-11 23:17:01 +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-15 21:37:55 +00:00
|
|
|
};
|
2014-03-11 23:27:46 +00:00
|
|
|
|
2014-03-24 17:41:08 +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-15 23:35:00 +00:00
|
|
|
* @param {Tone.Time} time
|
|
|
|
*/
|
2014-06-20 05:23:35 +00:00
|
|
|
Tone.Envelope.prototype.triggerExponentialRelease = function(time){
|
2014-04-11 23:17:01 +00:00
|
|
|
var startVal = this.control.getValue();
|
2014-04-06 00:47:59 +00:00
|
|
|
if (time){
|
|
|
|
startVal = (this.max - this.min) * this.sustain + this.min;
|
|
|
|
}
|
2014-04-11 23:17:01 +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-15 21:37:55 +00:00
|
|
|
};
|
2014-04-11 23:17:01 +00:00
|
|
|
|
2014-06-15 23:35:00 +00:00
|
|
|
/**
|
|
|
|
* pointer to the parent's connect method
|
2014-06-18 21:39:05 +00:00
|
|
|
* @private
|
2014-06-15 23:35:00 +00:00
|
|
|
*/
|
2014-04-11 23:17:01 +00:00
|
|
|
Tone.Envelope.prototype._connect = Tone.prototype.connect;
|
|
|
|
|
2014-06-15 23:35:00 +00:00
|
|
|
/**
|
2014-06-16 23:59:58 +00:00
|
|
|
* connect the envelope
|
|
|
|
*
|
|
|
|
* if the envelope is connected to a param, the params
|
|
|
|
* value will be set to 0 so that it doesn't interfere with the envelope
|
|
|
|
*
|
2014-06-15 23:35:00 +00:00
|
|
|
* @param {number} param
|
|
|
|
*/
|
2014-04-11 23:17:01 +00:00
|
|
|
Tone.Envelope.prototype.connect = function(param){
|
|
|
|
if (param instanceof AudioParam){
|
|
|
|
//set the initial value
|
2014-04-16 04:23:58 +00:00
|
|
|
param.value = 0;
|
2014-04-11 23:17:01 +00:00
|
|
|
}
|
|
|
|
this._connect(param);
|
2014-06-15 21:37:55 +00:00
|
|
|
};
|
2014-04-06 00:47:59 +00:00
|
|
|
|
2014-06-20 05:23:35 +00:00
|
|
|
/**
|
|
|
|
* disconnect and dispose
|
|
|
|
*/
|
|
|
|
Tone.Envelope.prototype.dispose = function(){
|
|
|
|
this.control.dispose();
|
|
|
|
this.control = null;
|
|
|
|
};
|
|
|
|
|
2014-04-06 00:47:59 +00:00
|
|
|
return Tone.Envelope;
|
|
|
|
});
|