Tone.js/Tone/component/Envelope.js

199 lines
4.9 KiB
JavaScript
Raw Normal View History

define(["Tone/core/Tone", "Tone/signal/Signal", "Tone/signal/Pow"], function(Tone){
2014-03-11 23:27:46 +00:00
"use strict";
2014-06-15 23:35:00 +00:00
/**
* @class ADSR envelope generator attaches to an AudioParam or Signal.
* Includes an optional exponent
2014-06-16 23:59:58 +00:00
*
* @constructor
* @extends {Tone}
2014-12-02 06:42:08 +00:00
* @param {Tone.Time|Object} [attack=0.01] the attack time in seconds
* @param {Tone.Time} [decay=0.1] the decay time in seconds
* @param {number} [sustain=0.5] a percentage (0-1) of the full amplitude
* @param {Tone.Time} [release=1] the release time in seconds
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 attack time in seconds
* @type {number}
*/
this.attack = options.attack;
/**
* the decay time in seconds
* @type {number}
*/
this.decay = options.decay;
/**
* the sustain is a value between 0-1
* @type {number}
*/
this.sustain = options.sustain;
/**
* the release time in seconds
* @type {number}
*/
this.release = options.release;
/**
2014-11-02 01:54:40 +00:00
* the signal
* @type {Tone.Signal}
* @private
*/
2014-11-02 01:54:40 +00:00
this._sig = new Tone.Signal(0);
2014-04-06 00:47:59 +00:00
/**
* scale the incoming signal by an exponent
* @type {Tone.Pow}
* @private
*/
this._exp = this.output = new Tone.Pow(options.exponent);
//connections
2014-12-01 02:32:09 +00:00
this._sig.connect(this._exp);
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
*/
Tone.Envelope.defaults = {
"attack" : 0.01,
"decay" : 0.1,
"sustain" : 0.5,
"release" : 1,
2014-11-02 01:54:40 +00:00
"exponent" : 1
};
/**
* 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.exponent)) this.setExponent(params.exponent);
};
2014-08-24 16:12:40 +00:00
/**
* set the attack time
* @param {Tone.Time} time
*/
Tone.Envelope.prototype.setAttack = function(time){
this.attack = time;
2014-08-24 16:12:40 +00:00
};
/**
* set the decay time
* @param {Tone.Time} time
*/
Tone.Envelope.prototype.setDecay = function(time){
this.decay = time;
2014-08-24 16:12:40 +00:00
};
/**
* set the release time
* @param {Tone.Time} time
*/
Tone.Envelope.prototype.setRelease = function(time){
this.release = time;
2014-08-24 16:12:40 +00:00
};
/**
* set the sustain amount
* @param {number} sustain value between 0-1
*/
Tone.Envelope.prototype.setSustain = function(sustain){
this.sustain = sustain;
};
/**
* set the exponent which scales the signal
* @param {number} exp
*/
Tone.Envelope.prototype.setExponent = function(exp){
this._exp.setExponent(exp);
};
2014-08-24 16:12:40 +00:00
2014-11-02 01:54:40 +00:00
/**
* the envelope time multipler
* @type {number}
* @private
*/
Tone.Envelope.prototype._timeMult = 0.25;
2014-06-15 23:35:00 +00:00
/**
* attack->decay->sustain linear ramp
2014-12-02 06:42:08 +00:00
* @param {Tone.Time} [time=now]
* @param {number} [velocity=1] the velocity of the envelope scales the vales.
2014-09-04 02:36:56 +00:00
* number between 0-1
2014-06-15 23:35:00 +00:00
*/
2014-09-04 02:36:56 +00:00
Tone.Envelope.prototype.triggerAttack = function(time, velocity){
velocity = this.defaultArg(velocity, 1);
var attack = this.toSeconds(this.attack);
var decay = this.toSeconds(this.decay);
2014-11-02 01:54:40 +00:00
var scaledMax = velocity;
var sustainVal = this.sustain;
time = this.toSeconds(time);
2014-11-02 01:54:40 +00:00
this._sig.cancelScheduledValues(time);
this._sig.setTargetAtTime(scaledMax, time, attack * this._timeMult);
this._sig.setTargetAtTime(sustainVal, time + attack, decay * this._timeMult);
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-12-02 06:42:08 +00:00
* @param {Tone.Time} [time=now]
2014-06-15 23:35:00 +00:00
*/
2014-04-06 00:47:59 +00:00
Tone.Envelope.prototype.triggerRelease = function(time){
time = this.toSeconds(time);
2014-11-02 01:54:40 +00:00
this._sig.cancelScheduledValues(time);
var release = this.toSeconds(this.release);
2014-11-02 01:54:40 +00:00
this._sig.setTargetAtTime(0, time, release * this._timeMult);
2014-06-15 21:37:55 +00:00
};
2014-09-20 19:18:36 +00:00
/**
* trigger the attack and release after a sustain time
* @param {Tone.Time} duration the duration of the note
2014-12-02 06:42:08 +00:00
* @param {Tone.Time} [time=now] the time of the attack
* @param {number} [velocity=1] the velocity of the note
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));
};
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);
2014-11-02 01:54:40 +00:00
this._sig.dispose();
this._sig = null;
this._exp.dispose();
this._exp = null;
2014-06-20 05:23:35 +00:00
};
2014-04-06 00:47:59 +00:00
return Tone.Envelope;
});