Source: component/Envelope.js

define(["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){

	/**
	 *  Envelope 
	 *  ADR envelope generator attaches to an AudioParam or AudioNode
	 *
	 *  @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
	 */
	Tone.Envelope = function(attack, decay, sustain, release, minOutput, maxOutput){
		//extend Unit
		Tone.call(this);

		/** @type {number} */
		this.attack = this.toSeconds(this.defaultArg(attack, 0.01));
		/** @type {number} */
		this.decay = this.toSeconds(this.defaultArg(decay, 0.1));
		/** @type {number} */
		this.release = this.toSeconds(this.defaultArg(release, 1));
		/** @type {number} */
		this.sustain = this.toSeconds(this.defaultArg(sustain, 0.5));

		/** @type {number} */
		this.min = this.defaultArg(minOutput, 0);
		/** @type {number} */
		this.max = this.defaultArg(maxOutput, 1);
		
		/** @type {Tone.Signal} */
		this.control = new Tone.Signal(this.min);

		//connections
		this.chain(this.control, this.output);
	};

	Tone.extend(Tone.Envelope);

	/**
	 * attack->decay->sustain linear ramp
	 * @param  {Tone.Time=} time
	 */
	Tone.Envelope.prototype.triggerAttack = function(time){
		var sustainVal = (this.max - this.min) * this.sustain + this.min;
		if (!time){
			this.control.linearRampToValueNow(this.max, this.attack);
			this.control.linearRampToValueAtTime(sustainVal, this.now() + this.attack + this.decay);	
		} 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);
		}
	};

	/**
	 * attack->decay->sustain exponential attack and linear decay
	 * @param  {Tone.Time=} time
	 */
	Tone.Envelope.prototype.triggerExponentialAttack = function(time){
		var sustainVal = (this.max - this.min) * this.sustain + this.min;
		if (!time){
			this.control.exponentialRampToValueNow(this.max, this.attack);
			this.control.linearRampToValueAtTime(sustainVal, this.now() + this.attack + this.decay);	
		} 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);
		}
	};

	
	/**
	 * triggers the release of the envelope with a linear ramp
	 * @param  {Tone.Time=} time
	 */
	Tone.Envelope.prototype.triggerRelease = function(time){
		if (time){
			//if there's a time, start at the sustain value
			startVal = (this.max - this.min) * this.sustain + this.min;
			time = this.toSeconds(time);
			this.control.cancelScheduledValues(time);
			this.control.setValueAtTime(startVal, time);
			this.control.linearRampToValueAtTime(this.min, time + this.toSeconds(this.release));
		} else {
			this.control.linearRampToValueNow(this.min, this.toSeconds(this.release));
		}
	};


	/**
	 * triggers the release of the envelope with an exponential ramp
	 * 
	 * @param  {Tone.Time=} time
	 */
	Tone.Envelope.prototype.triggerExponentialRelease = function(time){
		if (time){
			//if there's a time, start at the sustain value
			startVal = (this.max - this.min) * this.sustain + this.min;
			time = this.toSeconds(time);
			this.control.cancelScheduledValues(time);
			this.control.setValueAtTime(startVal, time);
			this.control.exponentialRampToValueAtTime(this.min, time + this.toSeconds(this.release));
		} else {
			this.control.exponentialRampToValueNow(this.min, this.toSeconds(this.release));
		}
	};

	/**
	 * 	pointer to the parent's connect method
	 * 	@private
	 */
	Tone.Envelope.prototype._connect = Tone.prototype.connect;

	/**
	 * 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
	 * 
	 * @param  {number} param
	 */
	Tone.Envelope.prototype.connect = function(param){
		if (param instanceof AudioParam){
			//set the initial value
			param.value = 0;
		} 
		this._connect(param);
	};

	/**
	 *  disconnect and dispose
	 */
	Tone.Envelope.prototype.dispose = function(){
		this.control.dispose();
		this.control = null;
	};

	return Tone.Envelope;
});
Tone No Tone Copyright © 2014.
Documentation generated on Mon Jun 23 2014 13:34:05 GMT-0400 (EDT).