Tone.js/Tone/effect/AutoWah.js

210 lines
5.2 KiB
JavaScript
Raw Normal View History

2014-09-21 17:38:00 +00:00
define(["Tone/core/Tone", "Tone/component/Follower", "Tone/signal/ScaleExp",
"Tone/effect/Effect", "Tone/component/Filter"],
function(Tone){
2014-08-23 18:23:43 +00:00
"use strict";
2014-08-23 18:23:43 +00:00
/**
* @class Tone.AutoWah connects a Tone.Follower to a bandpass filter (Tone.Filter).
2015-06-22 05:20:57 +00:00
* The frequency of the filter is adjusted proportionally to the
2015-07-04 19:25:37 +00:00
* incoming signal's amplitude. Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna).
2014-08-23 18:23:43 +00:00
*
* @constructor
* @extends {Tone.Effect}
2015-06-22 05:20:57 +00:00
* @param {Frequency|Object} [baseFrequency] The frequency the filter is set
* to at the low point of the wah
* @param {Positive} [octaves] The number of octaves above the baseFrequency
* the filter will sweep to when fully open
* @param {Decibels} [sensitivity] The decibel threshold sensitivity for
2014-08-23 18:23:43 +00:00
* the incoming signal. Normal range of -40 to 0.
2015-02-27 21:53:10 +00:00
* @example
* var autoWah = new Tone.AutoWah(50, 6, -30).toMaster();
* //initialize the synth and connect to autowah
* var synth = new SimpleSynth.connect(autoWah);
* //Q value influences the effect of the wah - default is 2
* autoWah.Q.value = 6;
* //more audible on higher notes
* synth.triggerAttackRelease("C4", "8n")
2014-08-23 18:23:43 +00:00
*/
Tone.AutoWah = function(){
2014-08-23 18:23:43 +00:00
var options = this.optionsObject(arguments, ["baseFrequency", "octaves", "sensitivity"], Tone.AutoWah.defaults);
Tone.Effect.call(this, options);
2014-08-23 18:23:43 +00:00
/**
2015-06-22 05:20:57 +00:00
* The envelope follower. Set the attack/release
* timing to adjust how the envelope is followed.
2014-08-23 18:23:43 +00:00
* @type {Tone.Follower}
* @private
*/
2015-02-10 16:40:27 +00:00
this.follower = new Tone.Follower(options.follower);
2014-08-23 18:23:43 +00:00
/**
* scales the follower value to the frequency domain
* @type {Tone}
* @private
*/
2014-11-30 02:36:32 +00:00
this._sweepRange = new Tone.ScaleExp(0, 1, 0.5);
2014-08-23 18:23:43 +00:00
/**
* @type {number}
* @private
*/
this._baseFrequency = options.baseFrequency;
2014-08-23 18:23:43 +00:00
/**
* @type {number}
* @private
*/
this._octaves = options.octaves;
2014-08-23 18:23:43 +00:00
/**
2015-03-05 16:06:27 +00:00
* the input gain to adjust the sensitivity
2015-03-03 15:27:34 +00:00
* @type {GainNode}
2014-08-23 18:23:43 +00:00
* @private
*/
2015-03-03 15:27:34 +00:00
this._inputBoost = this.context.createGain();
2014-08-23 18:23:43 +00:00
/**
* @type {BiquadFilterNode}
* @private
*/
2015-02-10 16:40:27 +00:00
this._bandpass = new Tone.Filter({
"rolloff" : -48,
"frequency" : 0,
"Q" : options.Q,
});
2014-08-23 18:23:43 +00:00
/**
2015-02-10 16:40:27 +00:00
* @type {Tone.Filter}
2014-08-23 18:23:43 +00:00
* @private
*/
2015-02-10 16:40:27 +00:00
this._peaking = new Tone.Filter(0, "peaking");
2014-09-05 03:56:48 +00:00
this._peaking.gain.value = options.gain;
2014-08-23 18:23:43 +00:00
2015-02-10 16:40:27 +00:00
/**
2015-06-22 05:20:57 +00:00
* The gain of the filter.
2015-06-13 23:50:39 +00:00
* @type {Gain}
* @signal
2015-02-10 16:40:27 +00:00
*/
this.gain = this._peaking.gain;
/**
* The quality of the filter.
2015-06-22 05:20:57 +00:00
* @type {Positive}
2015-06-13 23:50:39 +00:00
* @signal
2015-02-10 16:40:27 +00:00
*/
this.Q = this._bandpass.Q;
2014-08-23 18:23:43 +00:00
//the control signal path
2015-03-03 15:27:34 +00:00
this.effectSend.chain(this._inputBoost, this.follower, this._sweepRange);
2014-08-23 18:23:43 +00:00
this._sweepRange.connect(this._bandpass.frequency);
this._sweepRange.connect(this._peaking.frequency);
//the filtered path
2014-12-01 02:32:09 +00:00
this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn);
2014-08-23 18:23:43 +00:00
//set the initial value
this._setSweepRange();
2015-02-10 16:40:27 +00:00
this.sensitivity = options.sensitivity;
2015-04-18 14:54:08 +00:00
this._readOnly(["gain", "Q"]);
2014-08-23 18:23:43 +00:00
};
Tone.extend(Tone.AutoWah, Tone.Effect);
/**
* @static
* @type {Object}
*/
Tone.AutoWah.defaults = {
"baseFrequency" : 100,
2014-09-04 04:32:44 +00:00
"octaves" : 6,
"sensitivity" : 0,
2014-09-05 03:56:48 +00:00
"Q" : 2,
"gain" : 2,
"follower" : {
2014-09-04 04:32:44 +00:00
"attack" : 0.3,
"release" : 0.5
}
};
2014-08-23 18:23:43 +00:00
/**
2015-06-22 05:20:57 +00:00
* The number of octaves that the filter will sweep above the
* baseFrequency.
2015-02-10 16:40:27 +00:00
* @memberOf Tone.AutoWah#
2015-06-22 05:20:57 +00:00
* @type {Number}
2015-02-10 16:40:27 +00:00
* @name octaves
2014-08-23 18:23:43 +00:00
*/
2015-02-10 16:40:27 +00:00
Object.defineProperty(Tone.AutoWah.prototype, "octaves", {
get : function(){
return this._octaves;
},
set : function(octaves){
this._octaves = octaves;
this._setSweepRange();
}
});
2015-01-20 12:42:31 +00:00
2014-08-23 18:23:43 +00:00
/**
2015-02-10 16:40:27 +00:00
* The base frequency from which the sweep will start from.
* @memberOf Tone.AutoWah#
2015-06-14 00:20:36 +00:00
* @type {Frequency}
2015-02-10 16:40:27 +00:00
* @name baseFrequency
2014-08-23 18:23:43 +00:00
*/
2015-02-10 16:40:27 +00:00
Object.defineProperty(Tone.AutoWah.prototype, "baseFrequency", {
get : function(){
return this._baseFrequency;
},
set : function(baseFreq){
this._baseFrequency = baseFreq;
this._setSweepRange();
}
});
2014-08-23 18:23:43 +00:00
2015-01-20 12:42:31 +00:00
/**
2015-02-10 16:40:27 +00:00
* The sensitivity to control how responsive to the input signal the filter is.
* @memberOf Tone.AutoWah#
2015-06-22 05:20:57 +00:00
* @type {Decibels}
2015-02-10 16:40:27 +00:00
* @name sensitivity
2015-01-20 12:42:31 +00:00
*/
2015-02-10 16:40:27 +00:00
Object.defineProperty(Tone.AutoWah.prototype, "sensitivity", {
get : function(){
2015-03-03 15:27:34 +00:00
return this.gainToDb(1 / this._inputBoost.gain.value);
2015-02-10 16:40:27 +00:00
},
set : function(sensitivy){
2015-03-03 15:27:34 +00:00
this._inputBoost.gain.value = 1 / this.dbToGain(sensitivy);
2015-02-10 16:40:27 +00:00
}
});
2015-01-20 12:42:31 +00:00
2014-08-23 18:23:43 +00:00
/**
* sets the sweep range of the scaler
* @private
*/
Tone.AutoWah.prototype._setSweepRange = function(){
2015-02-10 16:40:27 +00:00
this._sweepRange.min = this._baseFrequency;
this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2);
2014-08-25 13:57:36 +00:00
};
2014-08-23 18:23:43 +00:00
/**
2015-06-22 05:20:57 +00:00
* Clean up.
* @returns {Tone.AutoWah} this
2014-08-23 18:23:43 +00:00
*/
Tone.AutoWah.prototype.dispose = function(){
2014-08-23 20:08:08 +00:00
Tone.Effect.prototype.dispose.call(this);
2015-02-10 16:40:27 +00:00
this.follower.dispose();
this.follower = null;
2014-08-23 20:08:08 +00:00
this._sweepRange.dispose();
this._sweepRange = null;
2015-02-10 16:40:27 +00:00
this._bandpass.dispose();
2014-08-23 20:08:08 +00:00
this._bandpass = null;
2015-02-10 16:40:27 +00:00
this._peaking.dispose();
2014-08-23 20:08:08 +00:00
this._peaking = null;
2015-03-03 15:30:42 +00:00
this._inputBoost.disconnect();
this._inputBoost = null;
2015-04-18 14:54:08 +00:00
this._writable(["gain", "Q"]);
2015-02-10 16:40:27 +00:00
this.gain = null;
this.Q = null;
2015-02-02 18:22:16 +00:00
return this;
2014-08-23 18:23:43 +00:00
};
return Tone.AutoWah;
});