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
|
|
|
|
2014-09-04 04:41:40 +00:00
|
|
|
"use strict";
|
|
|
|
|
2014-08-23 18:23:43 +00:00
|
|
|
/**
|
2015-07-04 16:40:33 +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
|
2015-07-04 16:40:33 +00:00
|
|
|
* var autoWah = new Tone.AutoWah(50, 6, -30).toMaster();
|
|
|
|
* //initialize the synth and connect to autowah
|
2016-05-23 23:49:41 +00:00
|
|
|
* var synth = new Synth.connect(autoWah);
|
2015-07-04 16:40:33 +00:00
|
|
|
* //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
|
|
|
*/
|
2014-08-24 23:28:42 +00:00
|
|
|
Tone.AutoWah = function(){
|
2014-08-23 18:23:43 +00:00
|
|
|
|
2017-04-26 03:18:08 +00:00
|
|
|
var options = Tone.defaults(arguments, ["baseFrequency", "octaves", "sensitivity"], Tone.AutoWah);
|
2014-08-24 23:28:42 +00:00
|
|
|
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
|
|
|
|
*/
|
2014-08-24 23:28:42 +00:00
|
|
|
this._baseFrequency = options.baseFrequency;
|
2014-08-23 18:23:43 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @type {number}
|
|
|
|
* @private
|
|
|
|
*/
|
2014-08-24 23:28:42 +00:00
|
|
|
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
|
2016-09-20 03:53:07 +00:00
|
|
|
* @type {Tone.Gain}
|
2014-08-23 18:23:43 +00:00
|
|
|
* @private
|
|
|
|
*/
|
2016-09-20 03:53:07 +00:00
|
|
|
this._inputBoost = new Tone.Gain();
|
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-11-18 03:52:22 +00:00
|
|
|
* @type {Number}
|
2015-06-13 23:50:39 +00:00
|
|
|
* @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);
|
|
|
|
|
2014-08-24 23:28:42 +00:00
|
|
|
/**
|
|
|
|
* @static
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
2014-08-25 14:23:37 +00:00
|
|
|
Tone.AutoWah.defaults = {
|
2014-08-24 23:28:42 +00:00
|
|
|
"baseFrequency" : 100,
|
2014-09-04 04:32:44 +00:00
|
|
|
"octaves" : 6,
|
2014-08-24 23:28:42 +00:00
|
|
|
"sensitivity" : 0,
|
2014-09-05 03:56:48 +00:00
|
|
|
"Q" : 2,
|
|
|
|
"gain" : 2,
|
2014-08-24 23:28:42 +00:00
|
|
|
"follower" : {
|
2014-09-04 04:32:44 +00:00
|
|
|
"attack" : 0.3,
|
2014-08-24 23:28:42 +00:00
|
|
|
"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.
|
2015-06-14 00:54:29 +00:00
|
|
|
* @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;
|
2016-09-20 03:53:07 +00:00
|
|
|
this._inputBoost.dispose();
|
2015-03-03 15:30:42 +00:00
|
|
|
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;
|
|
|
|
});
|