Tone.js/Tone/effect/Phaser.js

203 lines
5 KiB
JavaScript
Raw Normal View History

2014-12-01 02:18:58 +00:00
define(["Tone/core/Tone", "Tone/component/LFO", "Tone/component/Filter", "Tone/effect/StereoEffect"],
2014-08-24 21:51:01 +00:00
function(Tone){
"use strict";
/**
* @class Tone.Phaser is a phaser effect. Phasers work by changing the phase
2015-07-04 19:25:37 +00:00
* of different frequency components of an incoming signal. Read more on
* [Wikipedia](https://en.wikipedia.org/wiki/Phaser_(effect)).
* Inspiration for this phaser comes from [Tuna.js](https://github.com/Dinahmoe/tuna/).
2014-08-24 21:51:01 +00:00
*
2014-12-01 02:18:58 +00:00
* @extends {Tone.StereoEffect}
2014-08-24 21:51:01 +00:00
* @constructor
2015-06-22 05:20:57 +00:00
* @param {Frequency|Object} [frequency] The speed of the phasing.
* @param {number} [depth] The depth of the effect.
* @param {Frequency} [baseFrequency] The base frequency of the filters.
2015-02-27 21:53:10 +00:00
* @example
2015-06-22 05:20:57 +00:00
* var phaser = new Tone.Phaser({
* "frequency" : 15,
* "depth" : 5,
* "baseFrequency" : 1000
* }).toMaster();
* var synth = new Tone.FMSynth().connect(phaser);
* synth.triggerAttackRelease("E3", "2n");
2014-08-24 21:51:01 +00:00
*/
Tone.Phaser = function(){
2014-08-24 21:51:01 +00:00
//set the defaults
2015-02-10 16:40:27 +00:00
var options = this.optionsObject(arguments, ["frequency", "depth", "baseFrequency"], Tone.Phaser.defaults);
2014-12-01 02:18:58 +00:00
Tone.StereoEffect.call(this, options);
2014-08-24 21:51:01 +00:00
/**
* the lfo which controls the frequency on the left side
* @type {Tone.LFO}
* @private
*/
2015-02-10 16:40:27 +00:00
this._lfoL = new Tone.LFO(options.frequency, 0, 1);
2014-08-24 21:51:01 +00:00
/**
* the lfo which controls the frequency on the right side
2014-08-24 21:51:01 +00:00
* @type {Tone.LFO}
* @private
*/
2015-02-10 16:40:27 +00:00
this._lfoR = new Tone.LFO(options.frequency, 0, 1);
this._lfoR.phase = 180;
2014-08-24 21:51:01 +00:00
/**
* the base modulation frequency
* @type {number}
* @private
*/
this._baseFrequency = options.baseFrequency;
/**
* the depth of the phasing
* @type {number}
* @private
*/
this._depth = options.depth;
2015-07-04 17:48:18 +00:00
/**
* The quality factor of the filters
* @type {Positive}
* @signal
*/
this.Q = new Tone.Signal(options.Q, Tone.Type.Positive);
2014-08-24 21:51:01 +00:00
/**
* the array of filters for the left side
2015-06-14 00:56:41 +00:00
* @type {Array}
2014-08-24 21:51:01 +00:00
* @private
*/
2015-07-04 17:48:18 +00:00
this._filtersL = this._makeFilters(options.stages, this._lfoL, this.Q);
2014-08-24 21:51:01 +00:00
/**
* the array of filters for the left side
2015-06-14 00:56:41 +00:00
* @type {Array}
* @private
*/
2015-07-04 17:48:18 +00:00
this._filtersR = this._makeFilters(options.stages, this._lfoR, this.Q);
2015-02-10 16:40:27 +00:00
/**
* the frequency of the effect
* @type {Tone.Signal}
*/
this.frequency = this._lfoL.frequency;
this.frequency.value = options.frequency;
2014-08-24 21:51:01 +00:00
//connect them up
this.effectSendL.connect(this._filtersL[0]);
this.effectSendR.connect(this._filtersR[0]);
this._filtersL[options.stages - 1].connect(this.effectReturnL);
this._filtersR[options.stages - 1].connect(this.effectReturnR);
//control the frequency with one LFO
this._lfoL.frequency.connect(this._lfoR.frequency);
2014-08-24 21:51:01 +00:00
//set the options
2015-02-10 16:40:27 +00:00
this.baseFrequency = options.baseFrequency;
this.depth = options.depth;
2014-08-24 21:51:01 +00:00
//start the lfo
this._lfoL.start();
this._lfoR.start();
2015-07-04 17:48:18 +00:00
this._readOnly(["frequency", "Q"]);
2014-08-24 21:51:01 +00:00
};
2014-12-01 02:18:58 +00:00
Tone.extend(Tone.Phaser, Tone.StereoEffect);
2014-08-24 21:51:01 +00:00
/**
* defaults
* @static
* @type {object}
*/
Tone.Phaser.defaults = {
2015-02-10 16:40:27 +00:00
"frequency" : 0.5,
2014-12-01 02:18:58 +00:00
"depth" : 10,
2015-07-04 17:48:18 +00:00
"stages" : 10,
"Q" : 10,
"baseFrequency" : 350,
};
/**
* @param {number} stages
* @returns {Array} the number of filters all connected together
* @private
*/
2014-09-05 04:36:55 +00:00
Tone.Phaser.prototype._makeFilters = function(stages, connectToFreq, Q){
var filters = new Array(stages);
//make all the filters
for (var i = 0; i < stages; i++){
var filter = this.context.createBiquadFilter();
filter.type = "allpass";
2015-07-04 17:48:18 +00:00
Q.connect(filter.Q);
connectToFreq.connect(filter.frequency);
filters[i] = filter;
}
this.connectSeries.apply(this, filters);
return filters;
2014-08-24 21:51:01 +00:00
};
/**
2015-02-10 16:40:27 +00:00
* The depth of the effect.
* @memberOf Tone.Phaser#
* @type {number}
* @name depth
2014-08-24 21:51:01 +00:00
*/
2015-02-10 16:40:27 +00:00
Object.defineProperty(Tone.Phaser.prototype, "depth", {
get : function(){
return this._depth;
},
set : function(depth){
this._depth = depth;
var max = this._baseFrequency + this._baseFrequency * depth;
this._lfoL.max = max;
this._lfoR.max = max;
}
});
2014-08-24 21:51:01 +00:00
/**
2015-02-10 16:40:27 +00:00
* The the base frequency of the filters.
* @memberOf Tone.Phaser#
* @type {number}
2015-02-10 16:40:27 +00:00
* @name baseFrequency
*/
2015-02-10 16:40:27 +00:00
Object.defineProperty(Tone.Phaser.prototype, "baseFrequency", {
get : function(){
return this._baseFrequency;
},
set : function(freq){
this._baseFrequency = freq;
this._lfoL.min = freq;
this._lfoR.min = freq;
this.depth = this._depth;
}
});
2014-08-24 21:51:01 +00:00
/**
* clean up
* @returns {Tone.Phaser} this
2014-08-24 21:51:01 +00:00
*/
Tone.Phaser.prototype.dispose = function(){
2014-12-01 02:18:58 +00:00
Tone.StereoEffect.prototype.dispose.call(this);
2015-07-04 17:48:18 +00:00
this._writable(["frequency", "Q"]);
this.Q.dispose();
this.Q = null;
this._lfoL.dispose();
this._lfoL = null;
this._lfoR.dispose();
this._lfoR = null;
for (var i = 0; i < this._filtersL.length; i++){
this._filtersL[i].disconnect();
this._filtersL[i] = null;
}
this._filtersL = null;
for (var j = 0; j < this._filtersR.length; j++){
this._filtersR[j].disconnect();
this._filtersR[j] = null;
}
this._filtersR = null;
2015-02-10 16:40:27 +00:00
this.frequency = null;
2015-02-02 18:22:16 +00:00
return this;
2014-08-24 21:51:01 +00:00
};
return Tone.Phaser;
});