2015-07-18 18:59:18 +00:00
|
|
|
define(["Tone/core/Tone", "Tone/signal/Signal", "Tone/signal/Pow", "Tone/core/Types"], function(Tone){
|
2014-03-11 23:27:46 +00:00
|
|
|
|
2014-09-04 04:41:40 +00:00
|
|
|
"use strict";
|
|
|
|
|
2014-06-15 23:35:00 +00:00
|
|
|
/**
|
2015-07-04 19:25:37 +00:00
|
|
|
* @class Tone.Envelope is an [ADSR](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope)
|
|
|
|
* envelope generator. Tone.Envelope outputs a signal which
|
2015-07-02 19:45:40 +00:00
|
|
|
* can be connected to an AudioParam or Tone.Signal.
|
2015-07-04 16:32:18 +00:00
|
|
|
* <img src="https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg">
|
2014-06-16 23:59:58 +00:00
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
* @extends {Tone}
|
2015-06-20 23:25:49 +00:00
|
|
|
* @param {Time} [attack] The amount of time it takes for the envelope to go from
|
|
|
|
* 0 to it's maximum value.
|
2015-06-14 00:20:36 +00:00
|
|
|
* @param {Time} [decay] The period of time after the attack that it takes for the envelope
|
|
|
|
* to fall to the sustain value.
|
|
|
|
* @param {NormalRange} [sustain] The percent of the maximum value that the envelope rests at until
|
|
|
|
* the release is triggered.
|
|
|
|
* @param {Time} [release] The amount of time after the release is triggered it takes to reach 0.
|
2015-02-27 21:53:10 +00:00
|
|
|
* @example
|
2015-06-20 23:25:49 +00:00
|
|
|
* //an amplitude envelope
|
2015-06-14 03:56:32 +00:00
|
|
|
* var gainNode = Tone.context.createGain();
|
|
|
|
* var env = new Tone.Envelope({
|
|
|
|
* "attack" : 0.1,
|
|
|
|
* "decay" : 0.2,
|
|
|
|
* "sustain" : 1,
|
|
|
|
* "release" : 0.8,
|
|
|
|
* });
|
|
|
|
* env.connect(gainNode.gain);
|
2014-06-15 23:35:00 +00:00
|
|
|
*/
|
2014-08-24 23:28:42 +00:00
|
|
|
Tone.Envelope = function(){
|
2014-08-23 20:38:06 +00:00
|
|
|
|
|
|
|
//get all of the defaults
|
2014-08-25 14:23:37 +00:00
|
|
|
var options = this.optionsObject(arguments, ["attack", "decay", "sustain", "release"], Tone.Envelope.defaults);
|
2014-08-24 16:12:40 +00:00
|
|
|
|
2014-08-23 20:38:06 +00:00
|
|
|
/**
|
2015-06-20 23:25:49 +00:00
|
|
|
* When triggerAttack is called, the attack time is the amount of
|
|
|
|
* time it takes for the envelope to reach it's maximum value.
|
2015-06-14 00:20:36 +00:00
|
|
|
* @type {Time}
|
2014-08-23 20:38:06 +00:00
|
|
|
*/
|
2014-10-02 17:23:04 +00:00
|
|
|
this.attack = options.attack;
|
2014-08-23 20:38:06 +00:00
|
|
|
|
|
|
|
/**
|
2015-06-20 23:25:49 +00:00
|
|
|
* After the attack portion of the envelope, the value will fall
|
|
|
|
* over the duration of the decay time to it's sustain value.
|
2015-06-14 00:20:36 +00:00
|
|
|
* @type {Time}
|
2014-08-23 20:38:06 +00:00
|
|
|
*/
|
2014-10-02 17:23:04 +00:00
|
|
|
this.decay = options.decay;
|
2014-08-23 20:38:06 +00:00
|
|
|
|
|
|
|
/**
|
2015-06-20 23:25:49 +00:00
|
|
|
* The sustain value is the value
|
|
|
|
* which the envelope rests at after triggerAttack is
|
|
|
|
* called, but before triggerRelease is invoked.
|
2015-06-14 00:20:36 +00:00
|
|
|
* @type {NormalRange}
|
2014-08-23 20:38:06 +00:00
|
|
|
*/
|
2014-10-02 17:23:04 +00:00
|
|
|
this.sustain = options.sustain;
|
2014-08-23 20:38:06 +00:00
|
|
|
|
|
|
|
/**
|
2015-06-20 23:25:49 +00:00
|
|
|
* After triggerRelease is called, the envelope's
|
|
|
|
* value will fall to it's miminum value over the
|
|
|
|
* duration of the release time.
|
2015-06-14 00:20:36 +00:00
|
|
|
* @type {Time}
|
2014-08-23 20:38:06 +00:00
|
|
|
*/
|
2014-10-02 17:23:04 +00:00
|
|
|
this.release = options.release;
|
2014-08-23 20:38:06 +00:00
|
|
|
|
2015-04-18 18:54:51 +00:00
|
|
|
/**
|
|
|
|
* the next time the envelope is attacked
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._nextAttack = Infinity;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the next time the envelope is decayed
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._nextDecay = Infinity;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the next time the envelope is sustain
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._nextSustain = Infinity;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the next time the envelope is released
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._nextRelease = Infinity;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the next time the envelope is at standby
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._nextStandby = Infinity;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the next time the envelope is at standby
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
2015-05-24 13:53:53 +00:00
|
|
|
this._attackCurve = Tone.Envelope.Type.Linear;
|
2015-04-18 18:54:51 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* the last recorded velocity value
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._peakValue = 1;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the minimum output value
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
2015-04-19 00:23:14 +00:00
|
|
|
this._minOutput = 0.0001;
|
2015-04-18 18:54:51 +00:00
|
|
|
|
2014-08-23 20:38:06 +00:00
|
|
|
/**
|
2014-11-02 01:54:40 +00:00
|
|
|
* the signal
|
|
|
|
* @type {Tone.Signal}
|
|
|
|
* @private
|
2014-08-23 20:38:06 +00:00
|
|
|
*/
|
2014-12-06 21:48:57 +00:00
|
|
|
this._sig = this.output = new Tone.Signal(0);
|
2015-04-18 18:54:51 +00:00
|
|
|
|
2015-04-20 14:42:27 +00:00
|
|
|
//set the attackCurve initially
|
|
|
|
this.attackCurve = options.attackCurve;
|
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-08-23 20:38:06 +00:00
|
|
|
/**
|
|
|
|
* the default parameters
|
|
|
|
* @static
|
2015-02-06 22:49:04 +00:00
|
|
|
* @const
|
2014-08-23 20:38:06 +00:00
|
|
|
*/
|
2014-08-25 14:23:37 +00:00
|
|
|
Tone.Envelope.defaults = {
|
2014-08-23 20:38:06 +00:00
|
|
|
"attack" : 0.01,
|
|
|
|
"decay" : 0.1,
|
|
|
|
"sustain" : 0.5,
|
|
|
|
"release" : 1,
|
2015-04-20 14:42:27 +00:00
|
|
|
"attackCurve" : "linear"
|
2014-08-23 20:38:06 +00:00
|
|
|
};
|
|
|
|
|
2014-11-02 01:54:40 +00:00
|
|
|
/**
|
|
|
|
* the envelope time multipler
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
Tone.Envelope.prototype._timeMult = 0.25;
|
|
|
|
|
2015-07-04 17:36:38 +00:00
|
|
|
/**
|
|
|
|
* Read the current value of the envelope. Useful for
|
|
|
|
* syncronizing visual output to the envelope.
|
|
|
|
* @memberOf Tone.Envelope#
|
|
|
|
* @type {Number}
|
|
|
|
* @name value
|
|
|
|
* @readOnly
|
|
|
|
*/
|
|
|
|
Object.defineProperty(Tone.Envelope.prototype, "value", {
|
|
|
|
get : function(){
|
|
|
|
return this._sig.value;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-04-18 18:54:51 +00:00
|
|
|
/**
|
2015-05-24 13:53:53 +00:00
|
|
|
* The slope of the attack. Either "linear" or "exponential".
|
2015-04-18 18:54:51 +00:00
|
|
|
* @memberOf Tone.Envelope#
|
2015-05-24 13:53:53 +00:00
|
|
|
* @type {string}
|
2015-04-20 14:42:27 +00:00
|
|
|
* @name attackCurve
|
2015-04-18 18:54:51 +00:00
|
|
|
* @example
|
2015-04-20 14:42:27 +00:00
|
|
|
* env.attackCurve = "linear";
|
2015-04-18 18:54:51 +00:00
|
|
|
*/
|
2015-04-20 14:42:27 +00:00
|
|
|
Object.defineProperty(Tone.Envelope.prototype, "attackCurve", {
|
2015-04-18 18:54:51 +00:00
|
|
|
get : function(){
|
2015-04-20 14:42:27 +00:00
|
|
|
return this._attackCurve;
|
2015-04-18 18:54:51 +00:00
|
|
|
},
|
|
|
|
set : function(type){
|
2015-05-24 13:53:53 +00:00
|
|
|
if (type === Tone.Envelope.Type.Linear ||
|
|
|
|
type === Tone.Envelope.Type.Exponential){
|
2015-04-20 14:42:27 +00:00
|
|
|
this._attackCurve = type;
|
2015-04-18 18:54:51 +00:00
|
|
|
} else {
|
2015-04-20 14:42:27 +00:00
|
|
|
throw Error("attackCurve must be either \"linear\" or \"exponential\". Invalid type: ", type);
|
2015-04-18 18:54:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the phase of the envelope at the specified time.
|
|
|
|
* @param {number} time
|
|
|
|
* @return {Tone.Envelope.Phase}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
Tone.Envelope.prototype._phaseAtTime = function(time){
|
|
|
|
if (this._nextRelease > time){
|
|
|
|
if (this._nextAttack <= time && this._nextDecay > time){
|
2015-05-24 13:53:53 +00:00
|
|
|
return Tone.Envelope.Phase.Attack;
|
2015-04-18 18:54:51 +00:00
|
|
|
} else if (this._nextDecay <= time && this._nextSustain > time){
|
2015-05-24 13:53:53 +00:00
|
|
|
return Tone.Envelope.Phase.Decay;
|
2015-04-18 18:54:51 +00:00
|
|
|
} else if (this._nextSustain <= time && this._nextRelease > time){
|
2015-05-24 13:53:53 +00:00
|
|
|
return Tone.Envelope.Phase.Sustain;
|
2015-04-18 18:54:51 +00:00
|
|
|
} else {
|
2015-05-24 13:53:53 +00:00
|
|
|
return Tone.Envelope.Phase.Standby;
|
2015-04-18 18:54:51 +00:00
|
|
|
}
|
|
|
|
} else if (this._nextRelease < time && this._nextStandby > time){
|
2015-05-24 13:53:53 +00:00
|
|
|
return Tone.Envelope.Phase.Release;
|
2015-04-18 18:54:51 +00:00
|
|
|
} else {
|
2015-05-24 13:53:53 +00:00
|
|
|
return Tone.Envelope.Phase.Standby;
|
2015-04-18 18:54:51 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-06-14 03:56:32 +00:00
|
|
|
/**
|
|
|
|
* https://github.com/jsantell/web-audio-automation-timeline
|
|
|
|
* MIT License, copyright (c) 2014 Jordan Santell
|
|
|
|
* @private
|
|
|
|
*/
|
2015-04-18 18:54:51 +00:00
|
|
|
Tone.Envelope.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {
|
|
|
|
return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);
|
|
|
|
};
|
2015-06-14 03:56:32 +00:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
2015-04-18 18:54:51 +00:00
|
|
|
Tone.Envelope.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {
|
|
|
|
return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
|
|
|
|
};
|
2015-06-14 03:56:32 +00:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
2015-04-18 18:54:51 +00:00
|
|
|
Tone.Envelope.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {
|
|
|
|
return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the envelopes value at the given time
|
|
|
|
* @param {number} time
|
|
|
|
* @param {number} velocity
|
|
|
|
* @return {number}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
Tone.Envelope.prototype._valueAtTime = function(time){
|
|
|
|
var attack = this.toSeconds(this.attack);
|
|
|
|
var decay = this.toSeconds(this.decay);
|
|
|
|
var release = this.toSeconds(this.release);
|
|
|
|
switch(this._phaseAtTime(time)){
|
2015-05-24 13:53:53 +00:00
|
|
|
case Tone.Envelope.Phase.Attack:
|
|
|
|
if (this._attackCurve === Tone.Envelope.Type.Linear){
|
2015-04-18 18:54:51 +00:00
|
|
|
return this._linearInterpolate(this._nextAttack, this._minOutput, this._nextAttack + attack, this._peakValue, time);
|
|
|
|
} else {
|
|
|
|
return this._exponentialInterpolate(this._nextAttack, this._minOutput, this._nextAttack + attack, this._peakValue, time);
|
|
|
|
}
|
|
|
|
break;
|
2015-05-24 13:53:53 +00:00
|
|
|
case Tone.Envelope.Phase.Decay:
|
2015-04-18 18:54:51 +00:00
|
|
|
return this._exponentialApproach(this._nextDecay, this._peakValue, this.sustain * this._peakValue, decay * this._timeMult, time);
|
2015-05-24 13:53:53 +00:00
|
|
|
case Tone.Envelope.Phase.Release:
|
2015-04-18 18:54:51 +00:00
|
|
|
return this._exponentialApproach(this._nextRelease, this._peakValue, this._minOutput, release * this._timeMult, time);
|
2015-05-24 13:53:53 +00:00
|
|
|
case Tone.Envelope.Phase.Sustain:
|
2015-04-18 18:54:51 +00:00
|
|
|
return this.sustain * this._peakValue;
|
2015-05-24 13:53:53 +00:00
|
|
|
case Tone.Envelope.Phase.Standby:
|
2015-04-18 18:54:51 +00:00
|
|
|
return this._minOutput;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-06-15 23:35:00 +00:00
|
|
|
/**
|
2015-02-27 21:53:10 +00:00
|
|
|
* Trigger the attack/decay portion of the ADSR envelope.
|
2015-06-20 23:25:49 +00:00
|
|
|
* @param {Time} [time=now] When the attack should start.
|
|
|
|
* @param {NormalRange} [velocity=1] The velocity of the envelope scales the vales.
|
2014-09-04 02:36:56 +00:00
|
|
|
* number between 0-1
|
2015-06-14 00:54:29 +00:00
|
|
|
* @returns {Tone.Envelope} this
|
2015-02-27 21:53:10 +00:00
|
|
|
* @example
|
|
|
|
* //trigger the attack 0.5 seconds from now with a velocity of 0.2
|
|
|
|
* env.triggerAttack("+0.5", 0.2);
|
2014-06-15 23:35:00 +00:00
|
|
|
*/
|
2014-09-04 02:36:56 +00:00
|
|
|
Tone.Envelope.prototype.triggerAttack = function(time, velocity){
|
2015-04-18 18:54:51 +00:00
|
|
|
//to seconds
|
|
|
|
time = this.toSeconds(time);
|
2014-10-02 17:23:04 +00:00
|
|
|
var attack = this.toSeconds(this.attack);
|
|
|
|
var decay = this.toSeconds(this.decay);
|
2015-04-18 18:54:51 +00:00
|
|
|
|
|
|
|
//get the phase and position
|
|
|
|
var valueAtTime = this._valueAtTime(time);
|
|
|
|
var attackPast = valueAtTime * attack;
|
|
|
|
|
|
|
|
//compute the timing
|
|
|
|
this._nextAttack = time - attackPast;
|
|
|
|
this._nextDecay = this._nextAttack + attack;
|
|
|
|
this._nextSustain = this._nextDecay + decay;
|
|
|
|
this._nextRelease = Infinity;
|
|
|
|
|
|
|
|
//get the values
|
|
|
|
this._peakValue = this.defaultArg(velocity, 1);
|
|
|
|
var scaledMax = this._peakValue;
|
2014-12-08 16:02:22 +00:00
|
|
|
var sustainVal = this.sustain * scaledMax;
|
2015-04-18 18:54:51 +00:00
|
|
|
|
|
|
|
//set the curve
|
2014-11-02 01:54:40 +00:00
|
|
|
this._sig.cancelScheduledValues(time);
|
2015-04-18 18:54:51 +00:00
|
|
|
this._sig.setValueAtTime(valueAtTime, time);
|
2015-05-24 13:53:53 +00:00
|
|
|
if (this._attackCurve === Tone.Envelope.Type.Linear){
|
2015-04-18 18:54:51 +00:00
|
|
|
this._sig.linearRampToValueAtTime(scaledMax, this._nextDecay);
|
|
|
|
} else {
|
|
|
|
this._sig.exponentialRampToValueAtTime(scaledMax, this._nextDecay);
|
|
|
|
}
|
|
|
|
this._sig.setTargetAtTime(sustainVal, this._nextDecay, decay * this._timeMult);
|
2015-02-02 17:49:13 +00:00
|
|
|
return this;
|
2014-06-15 21:37:55 +00:00
|
|
|
};
|
2014-06-15 23:35:00 +00:00
|
|
|
|
|
|
|
/**
|
2015-02-27 21:53:10 +00:00
|
|
|
* Triggers the release of the envelope.
|
2015-06-20 23:25:49 +00:00
|
|
|
* @param {Time} [time=now] When the release portion of the envelope should start.
|
2015-06-14 00:54:29 +00:00
|
|
|
* @returns {Tone.Envelope} this
|
2015-02-27 21:53:10 +00:00
|
|
|
* @example
|
|
|
|
* //trigger release immediately
|
|
|
|
* env.triggerRelease();
|
2014-06-15 23:35:00 +00:00
|
|
|
*/
|
2014-04-06 00:47:59 +00:00
|
|
|
Tone.Envelope.prototype.triggerRelease = function(time){
|
2014-09-03 21:31:29 +00:00
|
|
|
time = this.toSeconds(time);
|
2015-04-18 18:54:51 +00:00
|
|
|
var phase = this._phaseAtTime(time);
|
2014-10-02 17:23:04 +00:00
|
|
|
var release = this.toSeconds(this.release);
|
2015-04-18 18:54:51 +00:00
|
|
|
|
|
|
|
//computer the value at the start of the next release
|
|
|
|
var valueAtTime = this._valueAtTime(time);
|
|
|
|
this._peakValue = valueAtTime;
|
|
|
|
|
|
|
|
this._nextRelease = time;
|
|
|
|
this._nextStandby = this._nextRelease + release;
|
|
|
|
|
|
|
|
//set the values
|
|
|
|
this._sig.cancelScheduledValues(this._nextRelease);
|
|
|
|
|
|
|
|
//if the phase is in the attack still, must reschedule the rest of the attack
|
2015-05-24 13:53:53 +00:00
|
|
|
if (phase === Tone.Envelope.Phase.Attack){
|
2015-04-18 18:54:51 +00:00
|
|
|
this._sig.setCurrentValueNow();
|
2015-05-24 13:53:53 +00:00
|
|
|
if (this.attackCurve === Tone.Envelope.Type.Linear){
|
2015-04-18 18:54:51 +00:00
|
|
|
this._sig.linearRampToValueAtTime(this._peakValue, this._nextRelease);
|
|
|
|
} else {
|
|
|
|
this._sig.exponentialRampToValueAtTime(this._peakValue, this._nextRelease);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this._sig.setValueAtTime(this._peakValue, this._nextRelease);
|
|
|
|
}
|
|
|
|
this._sig.setTargetAtTime(this._minOutput, this._nextRelease, release * this._timeMult);
|
2015-02-02 17:49:13 +00:00
|
|
|
return this;
|
2014-06-15 21:37:55 +00:00
|
|
|
};
|
2014-04-11 23:17:01 +00:00
|
|
|
|
2014-09-20 19:18:36 +00:00
|
|
|
/**
|
2015-06-20 23:25:49 +00:00
|
|
|
* triggerAttackRelease is shorthand for triggerAttack, then waiting
|
|
|
|
* some duration, then triggerRelease.
|
|
|
|
* @param {Time} duration The duration of the sustain.
|
|
|
|
* @param {Time} [time=now] When the attack should be triggered.
|
|
|
|
* @param {number} [velocity=1] The velocity of the envelope.
|
2015-06-14 00:54:29 +00:00
|
|
|
* @returns {Tone.Envelope} this
|
2015-02-27 21:53:10 +00:00
|
|
|
* @example
|
2015-06-20 23:25:49 +00:00
|
|
|
* //trigger the attack and then the release after 0.6 seconds.
|
|
|
|
* env.triggerAttackRelease(0.6);
|
2014-09-20 19:18:36 +00:00
|
|
|
*/
|
|
|
|
Tone.Envelope.prototype.triggerAttackRelease = function(duration, time, velocity) {
|
|
|
|
time = this.toSeconds(time);
|
|
|
|
this.triggerAttack(time, velocity);
|
|
|
|
this.triggerRelease(time + this.toSeconds(duration));
|
2015-02-02 17:49:13 +00:00
|
|
|
return this;
|
2014-09-20 19:18:36 +00:00
|
|
|
};
|
|
|
|
|
2014-06-15 23:35:00 +00:00
|
|
|
/**
|
2015-06-14 01:54:20 +00:00
|
|
|
* Borrows the connect method from Tone.Signal.
|
2014-08-23 20:38:06 +00:00
|
|
|
* @function
|
2015-06-20 23:25:49 +00:00
|
|
|
* @private
|
2014-06-15 23:35:00 +00:00
|
|
|
*/
|
2014-08-23 20:38:06 +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
|
|
|
/**
|
2015-06-20 23:25:49 +00:00
|
|
|
* Disconnect and dispose.
|
2015-06-14 00:54:29 +00:00
|
|
|
* @returns {Tone.Envelope} this
|
2014-06-20 05:23:35 +00:00
|
|
|
*/
|
|
|
|
Tone.Envelope.prototype.dispose = function(){
|
2014-08-23 20:38:06 +00:00
|
|
|
Tone.prototype.dispose.call(this);
|
2014-11-02 01:54:40 +00:00
|
|
|
this._sig.dispose();
|
|
|
|
this._sig = null;
|
2015-02-02 17:49:13 +00:00
|
|
|
return this;
|
2014-06-20 05:23:35 +00:00
|
|
|
};
|
|
|
|
|
2015-04-18 18:54:51 +00:00
|
|
|
/**
|
|
|
|
* The phase of the envelope.
|
|
|
|
* @enum {string}
|
|
|
|
*/
|
|
|
|
Tone.Envelope.Phase = {
|
2015-05-24 13:53:53 +00:00
|
|
|
Attack : "attack",
|
|
|
|
Decay : "decay",
|
|
|
|
Sustain : "sustain",
|
|
|
|
Release : "release",
|
|
|
|
Standby : "standby",
|
2015-04-18 18:54:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The phase of the envelope.
|
|
|
|
* @enum {string}
|
|
|
|
*/
|
|
|
|
Tone.Envelope.Type = {
|
2015-05-24 13:53:53 +00:00
|
|
|
Linear : "linear",
|
|
|
|
Exponential : "exponential",
|
2015-04-18 18:54:51 +00:00
|
|
|
};
|
|
|
|
|
2014-04-06 00:47:59 +00:00
|
|
|
return Tone.Envelope;
|
|
|
|
});
|