2014-09-21 17:39:18 +00:00
|
|
|
define(["Tone/core/Tone", "Tone/component/FeedbackCombFilter", "Tone/effect/StereoEffect", "Tone/signal/Scale"],
|
|
|
|
function(Tone){
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* an array of the comb filter delay time values
|
|
|
|
* @private
|
|
|
|
* @static
|
|
|
|
* @type {Array}
|
|
|
|
*/
|
|
|
|
var combFilterDelayTimes = [1687 / 25000, 1601 / 25000, 2053 / 25000, 2251 / 25000];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the resonances of each of the comb filters
|
|
|
|
* @private
|
|
|
|
* @static
|
|
|
|
* @type {Array}
|
|
|
|
*/
|
|
|
|
var combFilterResonances = [0.773, 0.802, 0.753, 0.733];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the allpass filter frequencies
|
|
|
|
* @private
|
|
|
|
* @static
|
|
|
|
* @type {Array}
|
|
|
|
*/
|
|
|
|
var allpassFilterFreqs = [347, 113, 37];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class a simple Schroeder Reverberators tuned by John Chowning in 1970
|
|
|
|
* made up of 3 allpass filters and 4 feedback comb filters.
|
|
|
|
* https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html
|
|
|
|
*
|
|
|
|
* @extends {Tone.Effect}
|
|
|
|
* @constructor
|
2015-02-27 21:53:10 +00:00
|
|
|
* @param {number} roomSize Coorelates to the decay time. Value between 0,1
|
|
|
|
* @example
|
|
|
|
* var freeverb = new Tone.Freeverb(0.4);
|
2014-09-21 17:39:18 +00:00
|
|
|
*/
|
|
|
|
Tone.JCReverb = function(){
|
2014-10-03 15:34:47 +00:00
|
|
|
|
|
|
|
var options = this.optionsObject(arguments, ["roomSize"], Tone.JCReverb.defaults);
|
|
|
|
Tone.StereoEffect.call(this, options);
|
2014-09-21 17:39:18 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* room size control values between [0,1]
|
2015-06-13 23:50:39 +00:00
|
|
|
* @type {NormalRange}
|
|
|
|
* @signal
|
2014-09-21 17:39:18 +00:00
|
|
|
*/
|
2015-05-24 13:45:15 +00:00
|
|
|
this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange);
|
2014-09-21 17:39:18 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* scale the room size
|
|
|
|
* @type {Tone.Scale}
|
|
|
|
* @private
|
|
|
|
*/
|
2014-11-30 02:36:32 +00:00
|
|
|
this._scaleRoomSize = new Tone.Scale(-0.733, 0.197);
|
2014-09-21 17:39:18 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* a series of allpass filters
|
|
|
|
* @type {Array.<BiquadFilterNode>}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._allpassFilters = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* parallel feedback comb filters
|
|
|
|
* @type {Array.<Tone.FeedbackCombFilter>}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._feedbackCombFilters = [];
|
|
|
|
|
|
|
|
//make the allpass filters
|
|
|
|
for (var af = 0; af < allpassFilterFreqs.length; af++) {
|
|
|
|
var allpass = this.context.createBiquadFilter();
|
|
|
|
allpass.type = "allpass";
|
|
|
|
allpass.frequency.value = allpassFilterFreqs[af];
|
|
|
|
this._allpassFilters.push(allpass);
|
|
|
|
}
|
|
|
|
|
|
|
|
//and the comb filters
|
|
|
|
for (var cf = 0; cf < combFilterDelayTimes.length; cf++) {
|
2014-11-03 16:34:02 +00:00
|
|
|
var fbcf = new Tone.FeedbackCombFilter(combFilterDelayTimes[cf], 0.1);
|
2014-09-21 17:39:18 +00:00
|
|
|
this._scaleRoomSize.connect(fbcf.resonance);
|
2015-02-10 21:44:27 +00:00
|
|
|
fbcf.resonance.value = combFilterResonances[cf];
|
2014-09-21 17:39:18 +00:00
|
|
|
this._allpassFilters[this._allpassFilters.length - 1].connect(fbcf);
|
|
|
|
if (cf < combFilterDelayTimes.length / 2){
|
|
|
|
fbcf.connect(this.effectReturnL);
|
|
|
|
} else {
|
|
|
|
fbcf.connect(this.effectReturnR);
|
|
|
|
}
|
|
|
|
this._feedbackCombFilters.push(fbcf);
|
|
|
|
}
|
|
|
|
|
|
|
|
//chain the allpass filters together
|
|
|
|
this.roomSize.connect(this._scaleRoomSize);
|
2014-11-30 22:37:29 +00:00
|
|
|
this.connectSeries.apply(this, this._allpassFilters);
|
2014-09-21 17:39:18 +00:00
|
|
|
this.effectSendL.connect(this._allpassFilters[0]);
|
|
|
|
this.effectSendR.connect(this._allpassFilters[0]);
|
2015-04-18 14:54:08 +00:00
|
|
|
this._readOnly(["roomSize"]);
|
2014-09-21 17:39:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Tone.extend(Tone.JCReverb, Tone.StereoEffect);
|
|
|
|
|
2014-10-03 15:34:47 +00:00
|
|
|
/**
|
|
|
|
* the default values
|
|
|
|
* @static
|
|
|
|
* @const
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
Tone.JCReverb.defaults = {
|
|
|
|
"roomSize" : 0.5
|
|
|
|
};
|
|
|
|
|
2014-09-21 17:39:18 +00:00
|
|
|
/**
|
|
|
|
* clean up
|
2015-02-02 18:22:16 +00:00
|
|
|
* @returns {Tone.JCReverb} `this`
|
2014-09-21 17:39:18 +00:00
|
|
|
*/
|
|
|
|
Tone.JCReverb.prototype.dispose = function(){
|
|
|
|
Tone.StereoEffect.prototype.dispose.call(this);
|
|
|
|
for (var apf = 0; apf < this._allpassFilters.length; apf++) {
|
|
|
|
this._allpassFilters[apf].disconnect();
|
|
|
|
this._allpassFilters[apf] = null;
|
|
|
|
}
|
|
|
|
this._allpassFilters = null;
|
|
|
|
for (var fbcf = 0; fbcf < this._feedbackCombFilters.length; fbcf++) {
|
|
|
|
this._feedbackCombFilters[fbcf].dispose();
|
|
|
|
this._feedbackCombFilters[fbcf] = null;
|
|
|
|
}
|
|
|
|
this._feedbackCombFilters = null;
|
2015-04-18 14:54:08 +00:00
|
|
|
this._writable(["roomSize"]);
|
2014-09-21 17:39:18 +00:00
|
|
|
this.roomSize.dispose();
|
|
|
|
this.roomSize = null;
|
2014-10-23 15:41:38 +00:00
|
|
|
this._scaleRoomSize.dispose();
|
2014-09-21 17:39:18 +00:00
|
|
|
this._scaleRoomSize = null;
|
2015-02-02 18:22:16 +00:00
|
|
|
return this;
|
2014-09-21 17:39:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return Tone.JCReverb;
|
|
|
|
});
|