diff --git a/Tone/core/Tone.js b/Tone/core/Tone.js index 0da4e9f6..eb0f30d0 100644 --- a/Tone/core/Tone.js +++ b/Tone/core/Tone.js @@ -577,7 +577,7 @@ define("Tone/core/Tone", [], function(){ _silentNode.connect(audioContext.destination); }); - console.log("Tone.js r2-dev"); + console.log("Tone.js r2"); return Tone; }); diff --git a/build/Tone.Preset.js b/build/Tone.Preset.js index cffd0582..9df76d42 100644 --- a/build/Tone.Preset.js +++ b/build/Tone.Preset.js @@ -50,10 +50,10 @@ define(["Tone/core/Tone", "Tone/effect/AutoWah"], function(Tone){ return Tone.AutoWah.prototype.preset; }); -define(["Tone/core/Tone", "Tone/effect/AutoWah"], function(Tone){ +define(["Tone/core/Tone", "Tone/effect/Chorus"], function(Tone){ /** - * named presets for the AutoWah + * named presets for the Chorus * @const * @static * @type {Object} @@ -84,7 +84,32 @@ define(["Tone/core/Tone", "Tone/effect/AutoWah"], function(Tone){ return Tone.Chorus.prototype.preset; }); -define(["Tone/core/Tone", "Tone/effect/AutoWah"], function(Tone){ +define(["Tone/core/Tone", "Tone/effect/Freeverb"], function(Tone){ + + /** + * named presets for Freeverb + * @const + * @static + * @type {Object} + */ + Tone.Freeverb.prototype.preset = { + "sewer" : { + "roomSize" : 0.8, + "dampening" : 0.05 + }, + "glassroom" : { + "roomSize" : 0.6, + "dampening" : 0.9 + }, + "bigplate" : { + "roomSize" : 0.9, + "dampening" : 0.2 + } + }; + + return Tone.Freeverb.prototype.preset; +}); +define(["Tone/core/Tone", "Tone/effect/Phaser"], function(Tone){ /** * named presets for the Phaser diff --git a/build/Tone.js b/build/Tone.js index 3795ce2b..a062457b 100644 --- a/build/Tone.js +++ b/build/Tone.js @@ -577,7 +577,7 @@ define("Tone/core/Tone", [], function(){ _silentNode.connect(audioContext.destination); }); - console.log("Tone.js r1"); + console.log("Tone.js r2"); return Tone; }); @@ -894,6 +894,260 @@ define('Tone/signal/Signal',["Tone/core/Tone"], function(Tone){ return Tone.Signal; }); +define('Tone/component/Envelope',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ + + + + /** + * @class ADSR envelope generator attaches to an AudioParam or Signal + * + * @constructor + * @extends {Tone} + * @param {Tone.Time|Object=} attack + * @param {Tone.Time=} decay + * @param {number=} sustain a percentage (0-1) of the full amplitude + * @param {Tone.Time=} release + */ + Tone.Envelope = function(){ + + //get all of the defaults + var options = this.optionsObject(arguments, ["attack", "decay", "sustain", "release"], Tone.Envelope.defaults); + + /** + * the output + * @type {GainNode} + */ + this.output = this.context.createGain(); + + /** + * the attack time in seconds + * @type {number} + */ + this.attack = this.toSeconds(options.attack); + + /** + * the decay time in seconds + * @type {number} + */ + this.decay = this.toSeconds(options.decay); + + /** + * the sustain is a value between 0-1 + * @type {number} + */ + this.sustain = this.toSeconds(options.sustain); + + /** + * the release time in seconds + * @type {number} + */ + this.release = this.toSeconds(options.release); + + /** + * the minimum output of the envelope + * @type {number} + */ + this.min = this.toSeconds(options.min); + + /** + * the maximum output of the envelope + * @type {number} + */ + this.max = this.toSeconds(options.max); + + /** + * the control signal + * @type {Tone.Signal} + * @private + */ + this._control = new Tone.Signal(this.min); + + //connections + this._control.connect(this.output); + }; + + Tone.extend(Tone.Envelope); + + /** + * the default parameters + * + * @static + */ + Tone.Envelope.defaults = { + "attack" : 0.01, + "decay" : 0.1, + "sustain" : 0.5, + "release" : 1, + "min" : 0, + "max" : 1 + }; + + // SETTERS // + + /** + * 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){ + 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.min)) this.setMin(params.min); + if (!this.isUndef(params.max)) this.setMax(params.max); + }; + + /** + * set the attack time + * @param {Tone.Time} time + */ + Tone.Envelope.prototype.setAttack = function(time){ + this.attack = this.toSeconds(time); + }; + + /** + * set the decay time + * @param {Tone.Time} time + */ + Tone.Envelope.prototype.setDecay = function(time){ + this.decay = this.toSeconds(time); + }; + + /** + * set the release time + * @param {Tone.Time} time + */ + Tone.Envelope.prototype.setRelease = function(time){ + this.release = this.toSeconds(time); + }; + + /** + * set the sustain amount + * @param {number} sustain value between 0-1 + */ + Tone.Envelope.prototype.setSustain = function(sustain){ + this.sustain = sustain; + }; + + /** + * set the envelope max + * @param {number} max + */ + Tone.Envelope.prototype.setMax = function(max){ + this.max = max; + }; + + /** + * set the envelope min + * @param {number} min + */ + Tone.Envelope.prototype.setMin = function(min){ + this.min = min; + //should move the signal to the min + this._control.setValueAtTime(this.min, this.now()); + }; + + /** + * attack->decay->sustain linear ramp + * @param {Tone.Time=} time + * @param {number=} [velocity=1] the velocity of the envelope scales the vales. + * number between 0-1 + */ + Tone.Envelope.prototype.triggerAttack = function(time, velocity){ + velocity = this.defaultArg(velocity, 1); + var scaledMax = this.max * velocity; + var sustainVal = (scaledMax - this.min) * this.sustain + this.min; + time = this.toSeconds(time); + this._control.cancelScheduledValues(time); + this._control.setTargetAtTime(scaledMax, time, this.attack / 4); + this._control.setTargetAtTime(sustainVal, time + this.attack, this.decay / 4); + }; + + /** + * triggers the release of the envelope with a linear ramp + * @param {Tone.Time=} time + */ + Tone.Envelope.prototype.triggerRelease = function(time){ + time = this.toSeconds(time); + this._control.cancelScheduledValues(time); + this._control.setTargetAtTime(this.min, time, this.toSeconds(this.release) / 4); + }; + + /** + * trigger the attack and release after a sustain time + * @param {Tone.Time} duration the duration of the note + * @param {Tone.Time=} time the time of the attack + * @param {number=} velocity the velocity of the note + */ + Tone.Envelope.prototype.triggerAttackRelease = function(duration, time, velocity) { + time = this.toSeconds(time); + this.triggerAttack(time, velocity); + this.triggerRelease(time + this.toSeconds(duration)); + }; + + /** + * borrows the connect method from {@link Tone.Signal} + * + * @function + */ + Tone.Envelope.prototype.connect = Tone.Signal.prototype.connect; + + /** + * disconnect and dispose + */ + Tone.Envelope.prototype.dispose = function(){ + Tone.prototype.dispose.call(this); + this._control.dispose(); + this._control = null; + }; + + return Tone.Envelope; +}); + +define('Tone/component/AmplitudeEnvelope',["Tone/core/Tone", "Tone/component/Envelope"], function(Tone){ + + + + /** + * @class An Envelope connected to a gain node which can be used as an amplitude envelope. + * + * @constructor + * @extends {Tone.Envelope} + * @param {Tone.Time|Object=} attack the attack time or an options object will all of the parameters + * @param {Tone.Time=} decay the decay time + * @param {number=} sustain the sustain amount + * @param {Tone.Time=} release the release time + */ + Tone.AmplitudeEnvelope = function(){ + + Tone.Envelope.apply(this, arguments); + + /** + * the input node + * @type {GainNode} + */ + this.input = this.context.createGain(); + + //disconenct the signal from the output + this._control.disconnect(); + //connect it to the output gain + this._control.connect(this.output.gain); + //input -> output + this.input.connect(this.output); + }; + + Tone.extend(Tone.AmplitudeEnvelope, Tone.Envelope); + + /** + * clean up + */ + Tone.AmplitudeEnvelope.prototype.dispose = function(){ + Tone.Envelope.prototype.dispose.call(this); + }; + + return Tone.AmplitudeEnvelope; +}); define('Tone/signal/Add',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ @@ -1593,205 +1847,347 @@ define('Tone/component/EQ',["Tone/core/Tone", "Tone/signal/Signal", "Tone/compon return Tone.EQ; }); -define('Tone/component/Envelope',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ - +define('Tone/signal/ScaleExp',["Tone/core/Tone", "Tone/signal/Add", "Tone/signal/Multiply", "Tone/signal/Signal"], function(Tone){ - /** - * @class ADSR envelope generator attaches to an AudioParam or Signal + * @class performs an exponential scaling on an input signal. + * Scales from the input range of inputMin to inputMax + * to the output range of outputMin to outputMax. + * + * @description If only two arguments are provided, the inputMin and inputMax are set to -1 and 1 * * @constructor * @extends {Tone} - * @param {Tone.Time|Object=} attack - * @param {Tone.Time=} decay - * @param {number=} sustain a percentage (0-1) of the full amplitude - * @param {Tone.Time=} release + * @param {number} inputMin + * @param {number} inputMax + * @param {number} outputMin + * @param {number=} outputMax + * @param {number=} [exponent=2] the exponent which scales the incoming signal */ - Tone.Envelope = function(){ + Tone.ScaleExp = function(inputMin, inputMax, outputMin, outputMax, exponent){ - //get all of the defaults - var options = this.optionsObject(arguments, ["attack", "decay", "sustain", "release"], Tone.Envelope.defaults); + Tone.call(this); + + //if there are only two args + if (arguments.length === 2){ + outputMin = inputMin; + outputMax = inputMax; + exponent = 2; + inputMin = -1; + inputMax = 1; + } else if (arguments.length === 3){ + exponent = outputMin; + outputMin = inputMin; + outputMax = inputMax; + inputMin = -1; + inputMax = 1; + } /** - * the output - * @type {GainNode} - */ - this.output = this.context.createGain(); - - /** - * the attack time in seconds - * @type {number} - */ - this.attack = this.toSeconds(options.attack); - - /** - * the decay time in seconds - * @type {number} - */ - this.decay = this.toSeconds(options.decay); - - /** - * the sustain is a value between 0-1 - * @type {number} - */ - this.sustain = this.toSeconds(options.sustain); - - /** - * the release time in seconds - * @type {number} - */ - this.release = this.toSeconds(options.release); - - /** - * the minimum output of the envelope - * @type {number} - */ - this.min = this.toSeconds(options.min); - - /** - * the maximum output of the envelope - * @type {number} - */ - this.max = this.toSeconds(options.max); - - /** - * the control signal - * @type {Tone.Signal} * @private + * @type {number} */ - this._control = new Tone.Signal(this.min); + this._inputMin = inputMin; + + /** + * @private + * @type {number} + */ + this._inputMax = inputMax; + + /** + * @private + * @type {number} + */ + this._outputMin = outputMin; + + /** + * @private + * @type {number} + */ + this._outputMax = outputMax; + + + /** + * @private + * @type {Tone.Add} + */ + this._plusInput = new Tone.Add(0); + + /** + * @private + * @type {Tone.Multiply} + */ + this._normalize = new Tone.Multiply(1); + + /** + * @private + * @type {Tone.Multiply} + */ + this._scale = new Tone.Multiply(1); + + /** + * @private + * @type {Tone.Add} + */ + this._plusOutput = new Tone.Add(0); + + /** + * @private + * @type {WaveShaperNode} + */ + this._expScaler = this.context.createWaveShaper(); //connections - this._control.connect(this.output); + this.chain(this.input, this._plusInput, this._normalize, this._expScaler, this._scale, this._plusOutput, this.output); + //set the scaling values + this._setScalingParameters(); + this.setExponent(this.defaultArg(exponent, 2)); }; - Tone.extend(Tone.Envelope); + Tone.extend(Tone.ScaleExp); /** - * the default parameters - * - * @static + * set the scaling parameters + * + * @private */ - Tone.Envelope.defaults = { - "attack" : 0.01, - "decay" : 0.1, - "sustain" : 0.5, - "release" : 1, - "min" : 0, - "max" : 1 + Tone.ScaleExp.prototype._setScalingParameters = function(){ + //components + this._plusInput.setValue(-this._inputMin); + this._scale.setValue((this._outputMax - this._outputMin)); + this._normalize.setValue(1 / (this._inputMax - this._inputMin)); + this._plusOutput.setValue(this._outputMin); }; - // SETTERS // - /** - * set all of the parameters in bulk - * @param {Object} param the name of member as the key - * and the value as the value + * set the exponential scaling curve + * @param {number} exp the exponent to raise the incoming signal to */ - Tone.Envelope.prototype.set = function(params){ - 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.min)) this.setMin(params.min); - if (!this.isUndef(params.max)) this.setMax(params.max); + Tone.ScaleExp.prototype.setExponent = function(exp){ + var curveLength = 1024; + var curve = new Float32Array(curveLength); + for (var i = 0; i < curveLength; i++){ + var normalized = (i / (curveLength)) * 2 - 1; + if (normalized >= 0){ + curve[i] = Math.pow(normalized, exp); + } else { + curve[i] = normalized; + } + } + this._expScaler.curve = curve; }; /** - * set the attack time - * @param {Tone.Time} time + * set the input min value + * @param {number} val */ - Tone.Envelope.prototype.setAttack = function(time){ - this.attack = this.toSeconds(time); + Tone.ScaleExp.prototype.setInputMin = function(val){ + this._inputMin = val; + this._setScalingParameters(); }; /** - * set the decay time - * @param {Tone.Time} time + * set the input max value + * @param {number} val */ - Tone.Envelope.prototype.setDecay = function(time){ - this.decay = this.toSeconds(time); + Tone.ScaleExp.prototype.setInputMax = function(val){ + this._inputMax = val; + this._setScalingParameters(); }; /** - * set the release time - * @param {Tone.Time} time + * set the output min value + * @param {number} val */ - Tone.Envelope.prototype.setRelease = function(time){ - this.release = this.toSeconds(time); + Tone.ScaleExp.prototype.setOutputMin = function(val){ + this._outputMin = val; + this._setScalingParameters(); }; /** - * set the sustain amount - * @param {number} sustain value between 0-1 + * set the output max value + * @param {number} val */ - Tone.Envelope.prototype.setSustain = function(sustain){ - this.sustain = sustain; + Tone.ScaleExp.prototype.setOutputMax = function(val){ + this._outputMax = val; + this._setScalingParameters(); }; /** - * set the envelope max - * @param {number} max - */ - Tone.Envelope.prototype.setMax = function(max){ - this.max = max; - }; - - /** - * set the envelope min - * @param {number} min - */ - Tone.Envelope.prototype.setMin = function(min){ - this.min = min; - //should move the signal to the min - this._control.setValueAtTime(this.min, this.now()); - }; - - /** - * attack->decay->sustain linear ramp - * @param {Tone.Time=} time - * @param {number=} [velocity=1] the velocity of the envelope scales the vales. - * number between 0-1 - */ - Tone.Envelope.prototype.triggerAttack = function(time, velocity){ - velocity = this.defaultArg(velocity, 1); - var scaledMax = this.max * velocity; - var sustainVal = (scaledMax - this.min) * this.sustain + this.min; - time = this.toSeconds(time); - this._control.cancelScheduledValues(time); - this._control.setTargetAtTime(scaledMax, time, this.attack / 4); - this._control.setTargetAtTime(sustainVal, time + this.attack, this.decay / 4); - }; - - /** - * triggers the release of the envelope with a linear ramp - * @param {Tone.Time=} time - */ - Tone.Envelope.prototype.triggerRelease = function(time){ - time = this.toSeconds(time); - this._control.cancelScheduledValues(time); - this._control.setTargetAtTime(this.min, time, this.toSeconds(this.release) / 4); - }; - - /** - * borrows the connect method from {@link Tone.Signal} + * borrows connect from {@link Tone.Signal} * * @function */ - Tone.Envelope.prototype.connect = Tone.Signal.prototype.connect; + Tone.ScaleExp.prototype.connect = Tone.Signal.prototype.connect; /** - * disconnect and dispose + * clean up */ - Tone.Envelope.prototype.dispose = function(){ + Tone.ScaleExp.prototype.dispose = function(){ Tone.prototype.dispose.call(this); - this._control.dispose(); - this._control = null; - }; + this._plusInput.dispose(); + this._plusOutput.dispose(); + this._normalize.dispose(); + this._scale.dispose(); + this._expScaler.disconnect(); + this._plusInput = null; + this._plusOutput = null; + this._scale = null; + this._normalize = null; + this._expScaler = null; + }; - return Tone.Envelope; + + return Tone.ScaleExp; }); +define('Tone/component/FeedbackCombFilter',["Tone/core/Tone", "Tone/signal/ScaleExp", "Tone/signal/Signal"], function(Tone){ + + + + /** + * @class A comb filter with feedback + * + * @extends {Tone} + * @constructor + * @param {number} [minDelay=0.1] the minimum delay time which the filter can have + */ + Tone.FeedbackCombFilter = function(minDelay){ + + Tone.call(this); + + minDelay = this.defaultArg(minDelay, 0.01); + //the delay * samplerate = number of samples. + // buffersize / number of samples = number of delays needed per buffer frame + var delayCount = Math.ceil(this.bufferSize / (minDelay * this.context.sampleRate)); + //set some ranges + delayCount = Math.min(delayCount, 10); + delayCount = Math.max(delayCount, 1); + + /** + * the number of filter delays + * @type {number} + * @private + */ + this._delayCount = delayCount; + + /** + * @type {Array.} + * @private + */ + this._delays = new Array(this._delayCount); + + /** + * the delayTime control + * @type {Tone.Signal} + * @private + */ + this._delayTime = new Tone.Signal(1); + + /** + * the resonance control + * @type {Tone.Signal} + */ + this.resonance = new Tone.Signal(0.5); + + /** + * scale the resonance value to the normal range + * @type {Tone.Scale} + * @private + */ + this._resScale = new Tone.ScaleExp(0, 1, 0.01, 1 / this._delayCount - 0.001, 0.5); + + /** + * internal flag for keeping track of when frequency + * correction has been used + * @type {boolean} + * @private + */ + this._highFrequencies = false; + + /** + * the feedback node + * @type {GainNode} + * @private + */ + this._feedback = this.context.createGain(); + + //make the filters + for (var i = 0; i < this._delayCount; i++) { + var delay = this.context.createDelay(); + delay.connect(this._feedback); + this._delayTime.connect(delay.delayTime); + this._delays[i] = delay; + } + + //connections + this.input.connect(this._delays[0]); + this._feedback.connect(this._delays[0]); + this.chain.apply(this, this._delays); + //resonance control + this.chain(this.resonance, this._resScale, this._feedback.gain); + this._feedback.connect(this.output); + //set the delay to the min value initially + this.setDelayTime(minDelay); + }; + + Tone.extend(Tone.FeedbackCombFilter); + + /** + * set the delay time of the comb filter + * auto corrects for sample offsets for small delay amounts + * + * @param {number} delayAmount the delay amount + * @param {Tone.Time=} time when the change should occur + */ + Tone.FeedbackCombFilter.prototype.setDelayTime = function(delayAmount, time) { + time = this.toSeconds(time); + //the number of samples to delay by + var sampleRate = this.context.sampleRate; + var delaySamples = sampleRate * delayAmount; + // delayTime corection when frequencies get high + time = this.toSeconds(time); + var cutoff = 100; + if (delaySamples < cutoff){ + this._highFrequencies = true; + var changeNumber = Math.round((delaySamples / cutoff) * this._delayCount); + for (var i = 0; i < changeNumber; i++) { + this._delays[i].delayTime.setValueAtTime(1 / sampleRate, time); + } + delayAmount = Math.floor(delaySamples) / sampleRate; + } else if (this._highFrequencies){ + this._highFrequencies = false; + for (var j = 0; j < this._delays.length; j++) { + this._delays[j].delayTime.setValueAtTime(0, time); + } + } + this._delayTime.setValueAtTime(delayAmount, time); + }; + + /** + * clean up + */ + Tone.FeedbackCombFilter.prototype.dispose = function(){ + Tone.prototype.dispose.call(this); + //dispose the filter delays + for (var i = 0; i < this._delays.length; i++) { + this._delays[i].disconnect(); + this._delays[i] = null; + } + this._delayTime.dispose(); + this.resonance.dispose(); + this._resScale.dispose(); + this._feedback.disconnect(); + this._delays = null; + this.resonance = null; + this._resScale = null; + this._feedback = null; + this._delayTime = null; + }; + + return Tone.FeedbackCombFilter; +}); define('Tone/signal/Threshold',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ @@ -1832,7 +2228,7 @@ define('Tone/signal/Threshold',["Tone/core/Tone", "Tone/signal/Signal"], functio this._thresh.connect(this._doubleThresh); this._setThresh(this._thresh, this.defaultArg(thresh, 0)); - this._setThresh(this._doubleThresh, 1); + this._setThresh(this._doubleThresh, 0.5); }; Tone.extend(Tone.Threshold); @@ -2699,7 +3095,9 @@ define('Tone/core/Clock',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone * @internal * @constructor * @extends {Tone} - * @param {number} rate the number of + * @param {number} rate the rate of the callback + * @param {function} callback the callback to be invoked with the time of the audio event + * NB: it is very important that only */ Tone.Clock = function(rate, callback){ @@ -2786,14 +3184,17 @@ define('Tone/core/Clock',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone this._upTick = false; var startTime = this.toSeconds(time); this._oscillator.start(startTime); + this._oscillator.onended = function(){}; }; /** * stop the clock * @param {Tone.Time} time the time when the clock should stop + * @param {function} onend called when the oscilator stops */ - Tone.Clock.prototype.stop = function(time){ + Tone.Clock.prototype.stop = function(time, onend){ var stopTime = this.toSeconds(time); + this._oscillator.onended = onend; this._oscillator.stop(stopTime); }; @@ -2806,11 +3207,19 @@ define('Tone/core/Clock',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone var bufferSize = this._jsNode.bufferSize; var incomingBuffer = event.inputBuffer.getChannelData(0); var upTick = this._upTick; + var self = this; for (var i = 0; i < bufferSize; i++){ var sample = incomingBuffer[i]; if (sample > 0 && !upTick){ upTick = true; - this.tick(now + this.samplesToSeconds(i)); + //get the callback out of audio thread + setTimeout(function(){ + //to account for the double buffering + var tickTime = now + self.samplesToSeconds(i + bufferSize * 2); + return function(){ + self.tick(tickTime); + }; + }(), 0); // jshint ignore:line } else if (sample < 0 && upTick){ upTick = false; } @@ -2825,6 +3234,7 @@ define('Tone/core/Clock',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone this._jsNode.disconnect(); this._controlSignal.dispose(); if (this._oscillator){ + this._oscillator.onended(); this._oscillator.disconnect(); } this._jsNode.onaudioprocess = function(){}; @@ -2981,14 +3391,16 @@ function(Tone){ * @private */ Tone.Transport.prototype._processTick = function(tickTime){ - processIntervals(tickTime); - processTimeouts(tickTime); - processTimeline(tickTime); - transportTicks += 1; - timelineTicks += 1; - if (this.loop){ - if (timelineTicks === loopEnd){ - this._setTicks(loopStart); + if (this.state === TransportState.STARTED){ + processIntervals(tickTime); + processTimeouts(tickTime); + processTimeline(tickTime); + transportTicks += 1; + timelineTicks += 1; + if (this.loop){ + if (timelineTicks === loopEnd){ + this._setTicks(loopStart); + } } } }; @@ -3057,8 +3469,8 @@ function(Tone){ var evnt = transportTimeline[i]; var callbackTick = evnt.callbackTick(); if (callbackTick === timelineTicks){ - evnt.doCallback(time); timelineProgress = i; + evnt.doCallback(time); } else if (callbackTick > timelineTicks){ break; } @@ -3306,19 +3718,29 @@ function(Tone){ */ Tone.Transport.prototype.stop = function(time){ if (this.state === TransportState.STARTED || this.state === TransportState.PAUSED){ - this.state = TransportState.STOPPED; var stopTime = this.toSeconds(time); - this._clock.stop(stopTime); - this._setTicks(0); - this.clearTimeouts(); + this._clock.stop(stopTime, this._onend.bind(this)); //call start on each of the synced sources for (var i = 0; i < SyncedSources.length; i++){ var source = SyncedSources[i].source; source.stop(stopTime); } + } else { + this._onend(); } }; + /** + * invoked when the transport is stopped + * @private + */ + Tone.Transport.prototype._onend = function(){ + transportTicks = 0; + this._setTicks(0); + this.clearTimeouts(); + this.state = TransportState.STOPPED; + }; + /** * pause the transport and all sources synced to the transport * @@ -3661,15 +4083,15 @@ function(Tone){ /** * convert ticks into seconds - * @param {string} transportTime + * @param {number} ticks * @param {number=} bpm * @param {number=} timeSignature * @return {number} seconds */ Tone.prototype.ticksToSeconds = function(ticks, bpm, timeSignature){ - ticks = parseInt(ticks); - var measure = this.notationToSeconds("4n", bpm, timeSignature); - return (measure * 4) / (tatum / ticks); + ticks = Math.floor(ticks); + var quater = this.notationToSeconds("4n", bpm, timeSignature); + return (quater * ticks) / (tatum); }; /** @@ -3757,8 +4179,7 @@ function(Tone){ //i know eval is evil, but i think it's safe here time = eval(time); // jshint ignore:line } catch (e){ - console.log("problem evaluating Tone.Time: "+oringalTime); - time = 0; + throw new EvalError("problem evaluating Tone.Time: "+oringalTime); } } else if (this.isNotation(time)){ time = this.notationToSeconds(time); @@ -3775,18 +4196,23 @@ function(Tone){ } }; + var TransportConstructor = Tone.Transport; //a single transport object Tone.Transport = new Tone.Transport(); - //set the bpm initially Tone.Transport.setBpm(120); Tone._initAudioContext(function(){ + //stop the clock + Tone.Transport.stop(); //get the previous bpm var bpm = Tone.Transport.getBpm(); - //make a new clocks - Tone.Transport._clock = new Tone.Clock(1, Tone.Transport._processTick.bind(Tone.Transport)); + //destory the old clock + Tone.Transport._clock.dispose(); + //make new Transport insides + TransportConstructor.call(Tone.Transport); //set the bpm Tone.Transport.setBpm(bpm); + }); return Tone.Transport; @@ -4311,6 +4737,199 @@ function(Tone){ return Tone.LFO; }); +define('Tone/component/LowpassCombFilter',["Tone/core/Tone", "Tone/signal/ScaleExp", "Tone/signal/Signal"], function(Tone){ + + + + /** + * @class A lowpass feedback comb filter. + * DelayNode -> Lowpass Filter -> feedback + * + * @extends {Tone} + * @constructor + * @param {number} [minDelay=0.1] the minimum delay time which the filter can have + */ + Tone.LowpassCombFilter = function(minDelay){ + + Tone.call(this); + + minDelay = this.defaultArg(minDelay, 0.01); + //the delay * samplerate = number of samples. + // buffersize / number of samples = number of delays needed per buffer frame + var delayCount = Math.ceil(this.bufferSize / (minDelay * this.context.sampleRate)); + //set some ranges + delayCount = Math.min(delayCount, 10); + delayCount = Math.max(delayCount, 1); + + /** + * the number of filter delays + * @type {number} + * @private + */ + this._filterDelayCount = delayCount; + + /** + * @type {Array.} + * @private + */ + this._filterDelays = new Array(this._filterDelayCount); + + /** + * the delayTime control + * @type {Tone.Signal} + * @private + */ + this._delayTime = new Tone.Signal(1); + + /** + * the dampening control + * @type {Tone.Signal} + */ + this.dampening = new Tone.Signal(3000); + + /** + * the resonance control + * @type {Tone.Signal} + */ + this.resonance = new Tone.Signal(0.5); + + /** + * scale the resonance value to the normal range + * @type {Tone.Scale} + * @private + */ + this._resScale = new Tone.ScaleExp(0, 1, 0.01, 1 / this._filterDelayCount - 0.001, 0.5); + + /** + * internal flag for keeping track of when frequency + * correction has been used + * @type {boolean} + * @private + */ + this._highFrequencies = false; + + /** + * the feedback node + * @type {GainNode} + * @private + */ + this._feedback = this.context.createGain(); + + //make the filters + for (var i = 0; i < this._filterDelayCount; i++) { + var filterDelay = new FilterDelay(this._delayTime, this.dampening); + filterDelay.connect(this._feedback); + this._filterDelays[i] = filterDelay; + } + + //connections + this.input.connect(this._filterDelays[0]); + this._feedback.connect(this._filterDelays[0]); + this.chain.apply(this, this._filterDelays); + //resonance control + this.chain(this.resonance, this._resScale, this._feedback.gain); + this._feedback.connect(this.output); + //set the delay to the min value initially + this.setDelayTime(minDelay); + }; + + Tone.extend(Tone.LowpassCombFilter); + + /** + * set the delay time of the comb filter + * auto corrects for sample offsets for small delay amounts + * + * @param {number} delayAmount the delay amount + * @param {Tone.Time=} time when the change should occur + */ + Tone.LowpassCombFilter.prototype.setDelayTime = function(delayAmount, time) { + time = this.toSeconds(time); + //the number of samples to delay by + var sampleRate = this.context.sampleRate; + var delaySamples = sampleRate * delayAmount; + // delayTime corection when frequencies get high + time = this.toSeconds(time); + var cutoff = 100; + if (delaySamples < cutoff){ + this._highFrequencies = true; + var changeNumber = Math.round((delaySamples / cutoff) * this._filterDelayCount); + for (var i = 0; i < changeNumber; i++) { + this._filterDelays[i].setDelay(1 / sampleRate, time); + } + delayAmount = Math.floor(delaySamples) / sampleRate; + } else if (this._highFrequencies){ + this._highFrequencies = false; + for (var j = 0; j < this._filterDelays.length; j++) { + this._filterDelays[j].setDelay(0, time); + } + } + this._delayTime.setValueAtTime(delayAmount, time); + }; + + /** + * clean up + */ + Tone.LowpassCombFilter.prototype.dispose = function(){ + Tone.prototype.dispose.call(this); + //dispose the filter delays + for (var i = 0; i < this._filterDelays.length; i++) { + this._filterDelays[i].dispose(); + this._filterDelays[i] = null; + } + this._delayTime.dispose(); + this.dampening.dispose(); + this.resonance.dispose(); + this._resScale.dispose(); + this._feedback.disconnect(); + this._filterDelays = null; + this.dampening = null; + this.resonance = null; + this._resScale = null; + this._feedback = null; + this._delayTime = null; + }; + + // BEGIN HELPER CLASS // + + /** + * FilterDelay + * @internal + * @constructor + * @extends {Tone} + */ + var FilterDelay = function(delayTime, filterFreq){ + this.delay = this.input = this.context.createDelay(); + delayTime.connect(this.delay.delayTime); + + this.filter = this.output = this.context.createBiquadFilter(); + filterFreq.connect(this.filter.frequency); + + this.filter.type = "lowpass"; + this.filter.Q.value = 0; + + this.delay.connect(this.filter); + }; + + Tone.extend(FilterDelay); + + FilterDelay.prototype.setDelay = function(amount, time) { + this.delay.delayTime.setValueAtTime(amount, time); + }; + + /** + * clean up + */ + FilterDelay.prototype.dispose = function(){ + this.delay.disconnect(); + this.filter.disconnect(); + this.delay = null; + this.filter = null; + }; + + // END HELPER CLASS // + + return Tone.LowpassCombFilter; +}); define('Tone/component/Merge',["Tone/core/Tone"], function(Tone){ @@ -4628,6 +5247,45 @@ define('Tone/component/Meter',["Tone/core/Tone", "Tone/core/Master"], function(T return Tone.Meter; }); +define('Tone/component/Mono',["Tone/core/Tone", "Tone/component/Merge"], function(Tone){ + + + + /** + * @class Transform the incoming mono or stereo signal into mono + * + * @extends {Tone} + * @constructor + */ + Tone.Mono = function(){ + Tone.call(this); + + /** + * merge the signal + * @type {Tone.Merge} + * @private + */ + this._merge = new Tone.Merge(); + + this.input.connect(this._merge, 0, 0); + this.input.connect(this._merge, 0, 1); + this.input.gain.value = this.dbToGain(-10); + this._merge.connect(this.output); + }; + + Tone.extend(Tone.Mono); + + /** + * clean up + */ + Tone.Mono.prototype.dispose = function(){ + Tone.prototype.dispose.call(this); + this._merge.dispose(); + this._merge = null; + }; + + return Tone.Mono; +}); define('Tone/component/Split',["Tone/core/Tone"], function(Tone){ @@ -5208,7 +5866,11 @@ define('Tone/core/Note',["Tone/core/Tone", "Tone/core/Transport"], function(Tone var notes = []; for (var inst in score){ var part = score[inst]; - if (Array.isArray(part)){ + if (inst === "tempo"){ + Tone.Transport.setBpm(part); + } else if (inst === "timeSignature"){ + Tone.Transport.setTimeSignature(part[0], part[1]); + } else if (Array.isArray(part)){ for (var i = 0; i < part.length; i++){ var noteDescription = part[i]; var note; @@ -5274,11 +5936,25 @@ define('Tone/core/Note',["Tone/core/Tone", "Tone/core/Transport"], function(Tone return noteName + octave.toString(); }; + /** + * convert an interval (in semitones) to a frequency ratio + * + * @example + * tone.intervalToFrequencyRatio(0); // returns 1 + * tone.intervalToFrequencyRatio(12); // returns 2 + * + * @param {number} interval the number of semitones above the base note + * @return {number} the frequency ratio + */ + Tone.prototype.intervalToFrequencyRatio = function(interval){ + return Math.pow(2,(interval/12)); + }; + /** * convert a midi note number into a note name * * @example - * tone.midiToNote(60) => "C3" + * tone.midiToNote(60); // returns "C3" * * @param {number} midiNumber the midi note number * @return {string} the note's name and octave @@ -5289,6 +5965,27 @@ define('Tone/core/Note',["Tone/core/Tone", "Tone/core/Transport"], function(Tone return noteIndexToNote[note] + octave; }; + /** + * convert a note to it's midi value + * + * @example + * tone.noteToMidi("C3"); // returns 60 + * + * @param {string} note the note name (i.e. "C3") + * @return {number} the midi value of that note + */ + Tone.prototype.noteToMidi = function(note){ + //break apart the note by frequency and octave + var parts = note.split(/(\d+)/); + if (parts.length === 3){ + var index = noteToIndex[parts[0].toLowerCase()]; + var octave = parts[1]; + return index + (parseInt(octave, 10) + 2) * 12; + } else { + return 0; + } + }; + return Tone.Note; }); define('Tone/effect/Effect',["Tone/core/Tone", "Tone/component/DryWet"], function(Tone){ @@ -5532,202 +6229,9 @@ define('Tone/effect/AutoPanner',["Tone/core/Tone", "Tone/effect/Effect", "Tone/c return Tone.AutoPanner; }); -define('Tone/signal/ScaleExp',["Tone/core/Tone", "Tone/signal/Add", "Tone/signal/Multiply", "Tone/signal/Signal"], function(Tone){ - - /** - * @class performs an exponential scaling on an input signal. - * Scales from the input range of inputMin to inputMax - * to the output range of outputMin to outputMax. - * - * @description If only two arguments are provided, the inputMin and inputMax are set to -1 and 1 - * - * @constructor - * @extends {Tone} - * @param {number} inputMin - * @param {number} inputMax - * @param {number} outputMin - * @param {number=} outputMax - * @param {number=} [exponent=2] the exponent which scales the incoming signal - */ - Tone.ScaleExp = function(inputMin, inputMax, outputMin, outputMax, exponent){ - - Tone.call(this); - - //if there are only two args - if (arguments.length === 2){ - outputMin = inputMin; - outputMax = inputMax; - exponent = 2; - inputMin = -1; - inputMax = 1; - } else if (arguments.length === 3){ - exponent = outputMin; - outputMin = inputMin; - outputMax = inputMax; - inputMin = -1; - inputMax = 1; - } - - /** - * @private - * @type {number} - */ - this._inputMin = inputMin; - - /** - * @private - * @type {number} - */ - this._inputMax = inputMax; - - /** - * @private - * @type {number} - */ - this._outputMin = outputMin; - - /** - * @private - * @type {number} - */ - this._outputMax = outputMax; - - - /** - * @private - * @type {Tone.Add} - */ - this._plusInput = new Tone.Add(0); - - /** - * @private - * @type {Tone.Multiply} - */ - this._normalize = new Tone.Multiply(1); - - /** - * @private - * @type {Tone.Multiply} - */ - this._scale = new Tone.Multiply(1); - - /** - * @private - * @type {Tone.Add} - */ - this._plusOutput = new Tone.Add(0); - - /** - * @private - * @type {WaveShaperNode} - */ - this._expScaler = this.context.createWaveShaper(); - - //connections - this.chain(this.input, this._plusInput, this._normalize, this._expScaler, this._scale, this._plusOutput, this.output); - //set the scaling values - this._setScalingParameters(); - this.setExponent(this.defaultArg(exponent, 2)); - }; - - Tone.extend(Tone.ScaleExp); - - /** - * set the scaling parameters - * - * @private - */ - Tone.ScaleExp.prototype._setScalingParameters = function(){ - //components - this._plusInput.setValue(-this._inputMin); - this._scale.setValue((this._outputMax - this._outputMin)); - this._normalize.setValue(1 / (this._inputMax - this._inputMin)); - this._plusOutput.setValue(this._outputMin); - }; - - /** - * set the exponential scaling curve - * @param {number} exp the exponent to raise the incoming signal to - */ - Tone.ScaleExp.prototype.setExponent = function(exp){ - var curveLength = 1024; - var curve = new Float32Array(curveLength); - for (var i = 0; i < curveLength; i++){ - var normalized = (i / (curveLength)) * 2 - 1; - if (normalized >= 0){ - curve[i] = Math.pow(normalized, exp); - } else { - curve[i] = normalized; - } - } - this._expScaler.curve = curve; - }; - - /** - * set the input min value - * @param {number} val - */ - Tone.ScaleExp.prototype.setInputMin = function(val){ - this._inputMin = val; - this._setScalingParameters(); - }; - - /** - * set the input max value - * @param {number} val - */ - Tone.ScaleExp.prototype.setInputMax = function(val){ - this._inputMax = val; - this._setScalingParameters(); - }; - - /** - * set the output min value - * @param {number} val - */ - Tone.ScaleExp.prototype.setOutputMin = function(val){ - this._outputMin = val; - this._setScalingParameters(); - }; - - /** - * set the output max value - * @param {number} val - */ - Tone.ScaleExp.prototype.setOutputMax = function(val){ - this._outputMax = val; - this._setScalingParameters(); - }; - - /** - * borrows connect from {@link Tone.Signal} - * - * @function - */ - Tone.ScaleExp.prototype.connect = Tone.Signal.prototype.connect; - - /** - * clean up - */ - Tone.ScaleExp.prototype.dispose = function(){ - Tone.prototype.dispose.call(this); - this._plusInput.dispose(); - this._plusOutput.dispose(); - this._normalize.dispose(); - this._scale.dispose(); - this._expScaler.disconnect(); - this._plusInput = null; - this._plusOutput = null; - this._scale = null; - this._normalize = null; - this._expScaler = null; - }; - - - return Tone.ScaleExp; -}); - -define('Tone/effect/AutoWah',["Tone/core/Tone", "Tone/component/Follower", "Tone/signal/ScaleExp", "Tone/effect/Effect"], function(Tone){ +define('Tone/effect/AutoWah',["Tone/core/Tone", "Tone/component/Follower", "Tone/signal/ScaleExp", +"Tone/effect/Effect", "Tone/component/Filter"], +function(Tone){ @@ -5891,7 +6395,7 @@ define('Tone/effect/AutoWah',["Tone/core/Tone", "Tone/component/Follower", "Tone return Tone.AutoWah; }); -define('Tone/signal/Modulo',["Tone/core/Tone", "Tone/signal/LessThan", "Tone/signal/Select", "Tone/signal/Not"], function(Tone){ +define('Tone/signal/Modulo',["Tone/core/Tone", "Tone/signal/Multiply"], function(Tone){ @@ -5903,15 +6407,15 @@ define('Tone/signal/Modulo',["Tone/core/Tone", "Tone/signal/LessThan", "Tone/sig * @constructor * @extends {Tone} * @param {number} modulus the modolus to apply - * @param {number=} bits optionally set the maximum bits the incoming signal can have. - * defaults to 4 meaning that incoming values must be in the range - * 0-32. (2^4 = 32); + * @param {number} [bits=8] optionally set the maximum bits the incoming signal can have. + * defaults to 8 meaning that incoming values must be in the range + * [-255,255]. (2^8 = 256); */ Tone.Modulo = function(modulus, bits){ Tone.call(this); - bits = this.defaultArg(bits, 4); + bits = this.defaultArg(bits, 8); /** * the array of Modulus Subroutine objects @@ -5925,11 +6429,9 @@ define('Tone/signal/Modulo',["Tone/core/Tone", "Tone/signal/LessThan", "Tone/sig var mod = new ModuloSubroutine(modulus, Math.pow(2, i)); this._modChain.push(mod); } - - //connect them up - this.input.connect(this._modChain[0]); this.chain.apply(this, this._modChain); - this._modChain[bits - 1].connect(this.output); + this.input.connect(this._modChain[0]); + this._modChain[this._modChain.length - 1].connect(this.output); }; Tone.extend(Tone.Modulo); @@ -5954,56 +6456,72 @@ define('Tone/signal/Modulo',["Tone/core/Tone", "Tone/signal/LessThan", "Tone/sig */ var ModuloSubroutine = function(modulus, multiple){ - Tone.call(this); - var val = modulus * multiple; /** - * @type {Tone.LessThan} - * @private + * the input node */ - this._lt = new Tone.LessThan(val); + this.input = this.context.createGain(); /** + * divide the incoming signal so it's on a 0 to 1 scale + * @type {Tone.Multiply} * @private - * @type {Tone.Not} */ - this._not = new Tone.Not(); + this._div = new Tone.Multiply(1 / val); /** + * apply the equation logic + * @type {WaveShaperNode} * @private - * @type {Tone.Add} */ - this._sub = new Tone.Add(-val); + this._operator = this.context.createWaveShaper(); - /** - * @private - * @type {Tone.Select} - */ - this._select = new Tone.Select(2); - - //connections - this.chain(this.input, this._lt, this._not, this._select.gate); - this.input.connect(this._sub); - this._sub.connect(this._select, 0, 1); - this.input.connect(this._select, 0, 0); - this._select.connect(this.output); + //connect it up + this.chain(this.input, this._div, this._operator); + this._makeCurve(val); }; Tone.extend(ModuloSubroutine); + /** + * make the operator curve + * @param {number} val + * @private + */ + ModuloSubroutine.prototype._makeCurve = function(val){ + var arrayLength = Math.pow(2, 18); + var curve = new Float32Array(arrayLength); + for (var i = 0; i < curve.length; i++) { + if (i === arrayLength - 1){ + curve[i] = -val; + } else if (i === 0){ + curve[i] = val; + } else { + curve[i] = 0; + } + } + this._operator.curve = curve; + }; + + /** + * @override the default connection to connect the operator and the input to the next node + * @private + */ + ModuloSubroutine.prototype.connect = function(node){ + this._operator.connect(node); + this.input.connect(node); + }; + /** * internal class clean up */ ModuloSubroutine.prototype.dispose = function(){ - this._lt.dispose(); - this._not.dispose(); - this._sub.dispose(); - this._select.dispose(); - this._lt = null; - this._not = null; - this._sub = null; - this._select = null; + Tone.prototype.dispose.call(this); + this._div.dispose(); + this._operator.disconnect(); + this._div = null; + this._operator = null; }; return Tone.Modulo; @@ -6123,7 +6641,7 @@ function(Tone){ return Tone.BitCrusher; }); -define('Tone/effect/StereoEffect',["Tone/core/Tone", "Tone/effect/Effect", "Tone/component/Split", "Tone/component/Merge"], +define('Tone/effect/StereoEffect',["Tone/core/Tone", "Tone/effect/Effect", "Tone/component/Split", "Tone/component/Merge", "Tone/component/Mono"], function(Tone){ @@ -6149,10 +6667,10 @@ function(Tone){ /** * make the incoming signal mono - * @type {Tone.Merge} + * @type {Tone.Mono} * @private */ - this._mono = new Tone.Merge(); + this._mono = new Tone.Mono(); /** * then split it @@ -6193,8 +6711,7 @@ function(Tone){ this.effectReturnR = this._merge.right; //connections - this.input.connect(this._mono, 0, 0); - this.input.connect(this._mono, 0, 1); + this.input.connect(this._mono); this._mono.connect(this._split); //dry wet connections this._mono.connect(this.dryWet.dry); @@ -6636,6 +7153,325 @@ define('Tone/effect/FeedbackDelay',["Tone/core/Tone", "Tone/effect/FeedbackEffec return Tone.FeedbackDelay; }); +define('Tone/effect/Freeverb',["Tone/core/Tone", "Tone/component/LowpassCombFilter", "Tone/effect/StereoEffect", "Tone/signal/Signal", "Tone/component/Split", "Tone/component/Merge"], +function(Tone){ + + + + /** + * an array of comb filter delay values from Freeverb implementation + * @static + * @private + * @type {Array} + */ + var combFilterTunings = [1557 / 44100, 1617 / 44100, 1491 / 44100, 1422 / 44100, 1277 / 44100, 1356 / 44100, 1188 / 44100, 1116 / 44100]; + + /** + * an array of allpass filter frequency values from Freeverb implementation + * @private + * @static + * @type {Array} + */ + var allpassFilterFrequencies = [225, 556, 441, 341]; + + /** + * @class Reverb based on the Freeverb + * + * @extends {Tone.Effect} + * @constructor + * @param {number} [roomSize=0.7] correlated to the decay time. + * value between (0,1) + * @param {number} [dampening=0.5] filtering which is applied to the reverb. + * value between [0,1] + */ + Tone.Freeverb = function(){ + + var options = this.optionsObject(arguments, ["roomSize", "dampening"], Tone.Freeverb.defaults); + Tone.StereoEffect.call(this, options); + + /** + * the roomSize value between (0,1) + * @type {Tone.Signal} + */ + this.roomSize = new Tone.Signal(options.roomSize); + + /** + * the amount of dampening + * value between [0,1] + * @type {Tone.Signal} + */ + this.dampening = new Tone.Signal(options.dampening); + + /** + * scale the dampening + * @type {Tone.ScaleExp} + * @private + */ + this._dampeningScale = new Tone.ScaleExp(0, 1, 100, 8000, 0.5); + + /** + * the comb filters + * @type {Array.} + * @private + */ + this._combFilters = []; + + /** + * the allpass filters on the left + * @type {Array.} + * @private + */ + this._allpassFilters = []; + + /** + * parallel feedback comb filters + * @type {Array.} + * @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++) { + var fbcf = new Tone.FeedbackCombFilter(combFilterDelayTimes[cf]); + this._scaleRoomSize.connect(fbcf.resonance); + fbcf.resonance.setValue(combFilterResonances[cf]); + 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); + this.chain.apply(this, this._allpassFilters); + this.effectSendL.connect(this._allpassFilters[0]); + this.effectSendR.connect(this._allpassFilters[0]); + }; + + Tone.extend(Tone.JCReverb, Tone.StereoEffect); + + /** + * set the room size + * @param {number} roomsize roomsize value between 0-1 + */ + Tone.JCReverb.prototype.setRoomSize = function(roomsize) { + this.roomSize.setValue(roomsize); + }; + + /** + * set multiple parameters at once with an object + * @param {Object} params the parameters as an object + */ + Tone.JCReverb.prototype.set = function(params){ + if (!this.isUndef(params.roomSize)) this.setRoomSize(params.roomSize); + Tone.StereoEffect.prototype.set.call(this, params); + }; + + /** + * clean up + */ + 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; + this.roomSize.dispose(); + this._scaleRoomSize.dispose(); + this.roomSize = null; + this._scaleRoomSize = null; + }; + + return Tone.JCReverb; +}); define('Tone/effect/StereoFeedbackEffect',["Tone/core/Tone", "Tone/effect/StereoEffect", "Tone/effect/FeedbackEffect"], function(Tone){ @@ -6985,7 +7821,71 @@ function(Tone){ return Tone.PingPongDelay; }); -define('Tone/instrument/Monophonic',["Tone/core/Tone", "Tone/source/Source", "Tone/signal/Signal", "Tone/core/Note"], function(Tone){ +define('Tone/instrument/Instrument',["Tone/core/Tone", "Tone/source/Source", "Tone/core/Note"], function(Tone){ + + + + /** + * @class Base-class for all instruments + * + * @constructor + * @extends {Tone} + */ + Tone.Instrument = function(){ + + /** + * the output + * @type {GainNode} + */ + this.output = this.context.createGain(); + }; + + Tone.extend(Tone.Instrument); + + /** + * @abstract + * @param {string|number} note the note to trigger + * @param {Tone.Time=} time the time to trigger the ntoe + * @param {number=} velocity the velocity to trigger the note + */ + Tone.Instrument.prototype.triggerAttack = function(){}; + + /** + * @abstract + * @param {Tone.Time=} time when to trigger the release + */ + Tone.Instrument.prototype.triggerRelease = function(){}; + + /** + * trigger the attack and then the release + * @param {string|number} note the note to trigger + * @param {Tone.Time=} duration the duration of the note + * @param {Tone.Time=} time the time of the attack + * @param {number} velocity the velocity + */ + Tone.Instrument.prototype.triggerAttackRelease = function(note, duration, time, velocity){ + time = this.toSeconds(time); + duration = this.toSeconds(duration); + this.triggerAttack(note, time, velocity); + this.triggerRelease(time + duration); + }; + + /** + * gets the setVolume method from {@link Tone.Source} + * @method + */ + Tone.Instrument.prototype.setVolume = Tone.Source.prototype.setVolume; + + /** + * clean up + */ + Tone.Instrument.prototype.dispose = function(){ + Tone.prototype.dispose.call(this); + }; + + return Tone.Instrument; +}); +define('Tone/instrument/Monophonic',["Tone/core/Tone", "Tone/instrument/Instrument", "Tone/signal/Signal"], function(Tone){ @@ -6999,15 +7899,11 @@ define('Tone/instrument/Monophonic',["Tone/core/Tone", "Tone/source/Source", "To */ Tone.Monophonic = function(options){ + Tone.Instrument.call(this); + //get the defaults options = this.defaultArg(options, Tone.Monophonic.defaults); - /** - * the instrument's output - * @type {GainNode} - */ - this.output = this.context.createGain(); - /** * the portamento time * @type {number} @@ -7015,7 +7911,7 @@ define('Tone/instrument/Monophonic',["Tone/core/Tone", "Tone/source/Source", "To this.portamento = options.portamento; }; - Tone.extend(Tone.Monophonic); + Tone.extend(Tone.Monophonic, Tone.Instrument); /** * @static @@ -7039,23 +7935,9 @@ define('Tone/instrument/Monophonic',["Tone/core/Tone", "Tone/source/Source", "To this.setNote(note, time); }; - /** - * trigger the attack and release after the specified duration - * - * @param {number|string} note the note as a number or a string note name - * @param {Tone.Time} duration the duration of the note - * @param {Tone.Time=} time if no time is given, defaults to now - * @param {number=} velocity the velocity of the attack (0-1) - */ - Tone.Monophonic.prototype.triggerAttackRelease = function(note, duration, time, velocity) { - time = this.toSeconds(time); - this.triggerAttack(note, time, velocity); - this.triggerRelease(time + this.toSeconds(duration)); - }; - /** * trigger the release portion of the envelope - * @param {Tone.Time=} [time=now] if no time is given, the release happens immediatly + * @param {Tone.Time} [time=now] if no time is given, the release happens immediatly */ Tone.Monophonic.prototype.triggerRelease = function(time){ this.triggerEnvelopeRelease(time); @@ -7064,16 +7946,16 @@ define('Tone/instrument/Monophonic',["Tone/core/Tone", "Tone/source/Source", "To /** * override this method with the actual method * @abstract - * @param {Tone.Time=} [time=now] the time the attack should happen - * @param {number=} [velocity=1] the velocity of the envelope + * @param {Tone.Time} [time=now] the time the attack should happen + * @param {number} [velocity=1] the velocity of the envelope */ Tone.Monophonic.prototype.triggerEnvelopeAttack = function() {}; /** * override this method with the actual method * @abstract - * @param {Tone.Time=} [time=now] the time the attack should happen - * @param {number=} [velocity=1] the velocity of the envelope + * @param {Tone.Time} [time=now] the time the attack should happen + * @param {number} [velocity=1] the velocity of the envelope */ Tone.Monophonic.prototype.triggerEnvelopeRelease = function() {}; @@ -7105,12 +7987,6 @@ define('Tone/instrument/Monophonic',["Tone/core/Tone", "Tone/source/Source", "To this.portamento = this.toSeconds(port); }; - /** - * set volume method borrowed form {@link Tone.Source} - * @function - */ - Tone.Monophonic.prototype.setVolume = Tone.Source.prototype.setVolume; - /** * bulk setter * @param {Object} params the params @@ -7134,7 +8010,7 @@ define('Tone/instrument/Monophonic',["Tone/core/Tone", "Tone/source/Source", "To * clean up */ Tone.Monophonic.prototype.dispose = function(){ - Tone.prototype.dispose.call(this); + Tone.Instrument.prototype.dispose.call(this); }; return Tone.Monophonic; @@ -7978,7 +8854,7 @@ define('Tone/source/Player',["Tone/core/Tone", "Tone/source/Source"], function(T return Tone.Player; }); -define('Tone/instrument/Sampler',["Tone/core/Tone", "Tone/source/Player", "Tone/component/Envelope", "Tone/component/Filter", "Tone/source/Source"], +define('Tone/instrument/Sampler',["Tone/core/Tone", "Tone/source/Player", "Tone/component/AmplitudeEnvelope", "Tone/component/Filter", "Tone/instrument/Instrument"], function(Tone){ @@ -7989,18 +8865,15 @@ function(Tone){ * envelope. * * @constructor - * @extends {Tone} + * @extends {Tone.Instrument} * @param {string|object} url the url of the audio file * @param {function} load called when the sample has been loaded */ Tone.Sampler = function(){ - var options = this.optionsObject(arguments, ["url", "load"], Tone.Sampler.defaults); + Tone.Instrument.call(this); - /** - * @type {GainNode} - */ - this.output = this.context.createGain(); + var options = this.optionsObject(arguments, ["url", "load"], Tone.Sampler.defaults); /** * the sample player @@ -8013,14 +8886,7 @@ function(Tone){ * the amplitude envelope * @type {Tone.Envelope} */ - this.envelope = new Tone.Envelope(options.envelope); - - /** - * the amplitude - * @type {GainNode} - * @private - */ - this._amplitude = this.context.createGain(); + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); /** * the filter envelope @@ -8035,12 +8901,11 @@ function(Tone){ this.filter = new Tone.Filter(options.filter); //connections - this.chain(this.player, this.filter, this._amplitude, this.output); - this.envelope.connect(this._amplitude.gain); + this.chain(this.player, this.filter, this.envelope, this.output); this.filterEnvelope.connect(this.filter.frequency); }; - Tone.extend(Tone.Sampler); + Tone.extend(Tone.Sampler, Tone.Instrument); /** * the default parameters @@ -8081,11 +8946,15 @@ function(Tone){ /** * start the sample - * - * @param {Tone.Time=} [time=now] the time when the note should start - * @param {number=} velocity the velocity of the note + * + * @param {number} [note=0] the interval in the sample should be played at 0 = no change + * @param {Tone.Time} [time=now] the time when the note should start + * @param {number} [velocity=1] the velocity of the note */ - Tone.Sampler.prototype.triggerAttack = function(time, velocity){ + Tone.Sampler.prototype.triggerAttack = function(note, time, velocity){ + time = this.toSeconds(time); + note = this.defaultArg(note, 0); + this.player.setPlaybackRate(this.intervalToFrequencyRatio(note), time); this.player.start(time); this.envelope.triggerAttack(time, velocity); this.filterEnvelope.triggerAttack(time); @@ -8094,38 +8963,19 @@ function(Tone){ /** * start the release portion of the sample * - * @param {Tone.Time=} [time=now] the time when the note should release + * @param {Tone.Time} [time=now] the time when the note should release */ Tone.Sampler.prototype.triggerRelease = function(time){ + time = this.toSeconds(time); this.filterEnvelope.triggerRelease(time); this.envelope.triggerRelease(time); }; - /** - * trigger the attack and release after the specified duration - * - * @param {number|string} note the note as a number or a string note name - * @param {Tone.Time} duration the duration of the note - * @param {Tone.Time=} time if no time is given, defaults to now - * @param {number=} velocity the velocity of the attack (0-1) - */ - Tone.Sampler.prototype.triggerAttackRelease = function(note, duration, time, velocity) { - time = this.toSeconds(time); - this.triggerAttack(note, time, velocity); - this.triggerRelease(time + this.toSeconds(duration)); - }; - - /** - * set volume method borrowed form {@link Tone.Source} - * @function - */ - Tone.Sampler.prototype.setVolume = Tone.Source.prototype.setVolume; - /** * clean up */ Tone.Sampler.prototype.dispose = function(){ - Tone.prototype.dispose.call(this); + Tone.Instrument.prototype.dispose.call(this); this.player.dispose(); this.filterEnvelope.dispose(); this.envelope.dispose(); @@ -8139,7 +8989,7 @@ function(Tone){ return Tone.Sampler; }); -define('Tone/instrument/MultiSampler',["Tone/core/Tone", "Tone/instrument/Sampler", "Tone/source/Source"], +define('Tone/instrument/MultiSampler',["Tone/core/Tone", "Tone/instrument/Sampler", "Tone/instrument/Instrument"], function(Tone){ @@ -8159,17 +9009,14 @@ function(Tone){ * sampler.triggerAttack("kick"); * * @constructor - * @extends {Tone} + * @extends {Tone.Instrument} * @param {Object} samples the samples used in this * @param {function} onload the callback to invoke when all * of the samples have been loaded */ Tone.MultiSampler = function(samples, onload){ - /** - * @type {GainNode} - */ - this.output = this.context.createGain(); + Tone.Instrument.call(this); /** * the array of voices @@ -8181,7 +9028,7 @@ function(Tone){ this._createSamples(samples, onload); }; - Tone.extend(Tone.MultiSampler); + Tone.extend(Tone.MultiSampler, Tone.Instrument); /** * creates all of the samples and tracks their loading @@ -8219,30 +9066,49 @@ function(Tone){ } }; - /** - * start a sample - * - * @param {string} sample the note name to start - * @param {Tone.Time=} [time=now] the time when the note should start - */ - Tone.MultiSampler.prototype.triggerAttack = function(sample, time){ + /** + * start a sample + * + * @param {string} sample the note name to start + * @param {Tone.Time=} [time=now] the time when the note should start + * @param {number} [velocity=1] the velocity of the note + */ + Tone.MultiSampler.prototype.triggerAttack = function(sample, time, velocity){ if (this.samples.hasOwnProperty(sample)){ - this.samples[sample].triggerAttack(time); + this.samples[sample].triggerAttack(0, time, velocity); } }; - /** - * start the release portion of the note - * - * @param {string} sample the note name to release - * @param {Tone.Time=} [time=now] the time when the note should release - */ + /** + * start the release portion of the note + * + * @param {string} sample the note name to release + * @param {Tone.Time=} [time=now] the time when the note should release + */ Tone.MultiSampler.prototype.triggerRelease = function(sample, time){ if (this.samples.hasOwnProperty(sample)){ this.samples[sample].triggerRelease(time); } }; + /** + * start the release portion of the note + * + * @param {string} sample the note name to release + * @param {Tone.Time} duration the duration of the note + * @param {Tone.Time} [time=now] the time when the note should start + * @param {number} [velocity=1] the velocity of the note + */ + Tone.MultiSampler.prototype.triggerAttackRelease = function(sample, duration, time, velocity){ + if (this.samples.hasOwnProperty(sample)){ + time = this.toSeconds(time); + duration = this.toSeconds(duration); + var samp = this.samples[sample]; + samp.triggerAttack(0, time, velocity); + samp.triggerRelease(time + duration); + } + }; + /** * sets all the samplers with these settings * @param {object} params the parameters to be applied @@ -8264,7 +9130,7 @@ function(Tone){ * clean up */ Tone.MultiSampler.prototype.dispose = function(){ - Tone.prototype.dispose.call(this); + Tone.Instrument.prototype.dispose.call(this); for (var samp in this.samples){ this.samples[samp].dispose(); this.samples[samp] = null; @@ -8275,6 +9141,311 @@ function(Tone){ return Tone.MultiSampler; }); +define('Tone/source/Noise',["Tone/core/Tone", "Tone/source/Source"], function(Tone){ + + + + /** + * @class Noise generator. + * Uses looped noise buffers to save on performance. + * + * @constructor + * @extends {Tone.Source} + * @param {string} type the noise type (white|pink|brown) + */ + Tone.Noise = function(type){ + + Tone.Source.call(this); + + /** + * @private + * @type {AudioBufferSourceNode} + */ + this._source = null; + + /** + * the buffer + * @private + * @type {AudioBuffer} + */ + this._buffer = null; + + /** + * set a callback function to invoke when the sample is over + * + * @type {function} + */ + this.onended = function(){}; + + this.setType(this.defaultArg(type, "white")); + }; + + Tone.extend(Tone.Noise, Tone.Source); + + /** + * set the noise type + * + * @param {string} type the noise type (white|pink|brown) + * @param {Tone.Time} time (optional) time that the set will occur + */ + Tone.Noise.prototype.setType = function(type, time){ + switch (type){ + case "white" : + this._buffer = _whiteNoise; + break; + case "pink" : + this._buffer = _pinkNoise; + break; + case "brown" : + this._buffer = _brownNoise; + break; + default : + this._buffer = _whiteNoise; + } + //if it's playing, stop and restart it + if (this.state === Tone.Source.State.STARTED){ + time = this.toSeconds(time); + //remove the listener + this._source.onended = undefined; + this._stop(time); + this._start(time); + } + }; + + /** + * internal start method + * + * @param {Tone.Time} time + * @private + */ + Tone.Noise.prototype._start = function(time){ + this._source = this.context.createBufferSource(); + this._source.buffer = this._buffer; + this._source.loop = true; + this.chain(this._source, this.output); + this._source.start(this.toSeconds(time)); + this._source.onended = this._onended.bind(this); + }; + + /** + * start the noise at a specific time + * + * @param {Tone.Time} time + */ + Tone.Noise.prototype.start = function(time){ + if (this.state === Tone.Source.State.STOPPED){ + this.state = Tone.Source.State.STARTED; + //make the source + this._start(time); + } + }; + + /** + * internal stop method + * + * @param {Tone.Time} time + * @private + */ + Tone.Noise.prototype._stop = function(time){ + this._source.stop(this.toSeconds(time)); + }; + + + /** + * stop the noise at a specific time + * + * @param {Tone.Time} time + */ + Tone.Noise.prototype.stop = function(time){ + if (this.state === Tone.Source.State.STARTED) { + if (this._buffer && this._source){ + if (!time){ + this.state = Tone.Source.State.STOPPED; + } + this._stop(time); + } + } + }; + + /** + * internal call when the buffer is done playing + * + * @private + */ + Tone.Noise.prototype._onended = function(){ + this.state = Tone.Source.State.STOPPED; + this.onended(); + }; + + /** + * dispose all the components + */ + Tone.Noise.prototype.dispose = function(){ + Tone.Source.prototype.dispose.call(this); + if (this._source !== null){ + this._source.disconnect(); + this._source = null; + } + this._buffer = null; + }; + + + /////////////////////////////////////////////////////////////////////////// + // THE BUFFERS + // borred heavily from http://noisehack.com/generate-noise-web-audio-api/ + /////////////////////////////////////////////////////////////////////////// + + /** + * static noise buffers + * + * @static + * @private + * @type {AudioBuffer} + */ + var _pinkNoise = null, _brownNoise = null, _whiteNoise = null; + + Tone._initAudioContext(function(audioContext){ + + var sampleRate = audioContext.sampleRate; + + //four seconds per buffer + var bufferLength = sampleRate * 4; + + //fill the buffers + _pinkNoise = (function() { + var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); + for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++){ + var channel = buffer.getChannelData(channelNum); + var b0, b1, b2, b3, b4, b5, b6; + b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0; + for (var i = 0; i < bufferLength; i++) { + var white = Math.random() * 2 - 1; + b0 = 0.99886 * b0 + white * 0.0555179; + b1 = 0.99332 * b1 + white * 0.0750759; + b2 = 0.96900 * b2 + white * 0.1538520; + b3 = 0.86650 * b3 + white * 0.3104856; + b4 = 0.55000 * b4 + white * 0.5329522; + b5 = -0.7616 * b5 - white * 0.0168980; + channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; + channel[i] *= 0.11; // (roughly) compensate for gain + b6 = white * 0.115926; + } + } + return buffer; + }()); + + _brownNoise = (function() { + var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); + for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++){ + var channel = buffer.getChannelData(channelNum); + var lastOut = 0.0; + for (var i = 0; i < bufferLength; i++) { + var white = Math.random() * 2 - 1; + channel[i] = (lastOut + (0.02 * white)) / 1.02; + lastOut = channel[i]; + channel[i] *= 3.5; // (roughly) compensate for gain + } + } + return buffer; + })(); + + _whiteNoise = (function(){ + var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); + for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++){ + var channel = buffer.getChannelData(channelNum); + for (var i = 0; i < bufferLength; i++){ + channel[i] = Math.random() * 2 - 1; + } + } + return buffer; + }()); + }); + + return Tone.Noise; +}); +define('Tone/instrument/PluckSynth',["Tone/core/Tone", "Tone/instrument/Instrument", "Tone/source/Noise", "Tone/component/LowpassCombFilter"], function(Tone){ + + + + /** + * @class Karplus-String string synthesis. + * + * @constructor + * @extends {Tone.Instrument} + */ + Tone.PluckSynth = function(){ + + Tone.Instrument.call(this); + + /** + * @type {Tone.Noise} + * @private + */ + this._noise = new Tone.Noise("pink"); + + /** + * the amount of noise at the attack. + * nominal range of [0.1, 20] + * @type {number} + */ + this.attackNoise = 1; + + /** + * the LFCF + * @type {Tone.LowpassCombFilter} + * @private + */ + this._lfcf = new Tone.LowpassCombFilter(1 / 440); + + /** + * the resonance control + * @type {Tone.Signal} + */ + this.resonance = this._lfcf.resonance; + + /** + * the dampening control. i.e. the lowpass filter frequency of the comb filter + * @type {Tone.Signal} + */ + this.dampening = this._lfcf.dampening; + + //connections + this._noise.connect(this._lfcf); + this._lfcf.connect(this.output); + }; + + Tone.extend(Tone.PluckSynth, Tone.Instrument); + + + /** + * trigger the attack portion + */ + Tone.PluckSynth.prototype.triggerAttack = function(note, time) { + if (typeof note === "string"){ + note = this.noteToFrequency(note); + } + time = this.toSeconds(time); + var delayAmount = 1 / note; + this._lfcf.setDelayTime(delayAmount, time); + this._noise.start(time); + this._noise.stop(time + delayAmount * this.attackNoise); + }; + + /** + * clean up + */ + Tone.PluckSynth.prototype.dispose = function(){ + Tone.Instrument.prototype.dispose.call(this); + this._noise.dispose(); + this._lfcf.dispose(); + this._noise = null; + this._lfcf = null; + this.dampening = null; + this.resonance = null; + }; + + return Tone.PluckSynth; +}); define('Tone/instrument/PolySynth',["Tone/core/Tone", "Tone/instrument/MonoSynth", "Tone/source/Source"], function(Tone){ @@ -8291,21 +9462,17 @@ function(Tone){ * synth.setPreset("Pianoetta"); * * @constructor - * @extends {Tone} - * @param {number|Object=} [polyphony=4] the number of voices to create - * @param {function=} [voice=Tone.MonoSynth] the constructor of the voices + * @extends {Tone.Instrument} + * @param {number|Object} [polyphony=4] the number of voices to create + * @param {function} [voice=Tone.MonoSynth] the constructor of the voices * uses Tone.MonoSynth by default - * @param {Object=} voiceOptions the options to pass to the voice + * @param {Object} voiceOptions the options to pass to the voice */ Tone.PolySynth = function(){ - var options = this.optionsObject(arguments, ["polyphony", "voice", "voiceOptions"], Tone.PolySynth.defaults); + Tone.Instrument.call(this); - /** - * the output - * @type {GainNode} - */ - this.output = this.context.createGain(); + var options = this.optionsObject(arguments, ["polyphony", "voice", "voiceOptions"], Tone.PolySynth.defaults); /** * the array of voices @@ -8339,7 +9506,7 @@ function(Tone){ this._freeVoices = this._voices.slice(0); }; - Tone.extend(Tone.PolySynth); + Tone.extend(Tone.PolySynth, Tone.Instrument); /** * the defaults @@ -8421,17 +9588,11 @@ function(Tone){ } }; - /** - * set volume method borrowed form {@link Tone.Source} - * @function - */ - Tone.PolySynth.prototype.setVolume = Tone.Source.prototype.setVolume; - /** * clean up */ Tone.PolySynth.prototype.dispose = function(){ - Tone.prototype.dispose.call(this); + Tone.Instrument.prototype.dispose.call(this); for (var i = 0; i < this._voices.length; i++){ this._voices[i].dispose(); this._voices[i] = null; @@ -8967,228 +10128,6 @@ define('Tone/source/Microphone',["Tone/core/Tone", "Tone/source/Source"], functi return Tone.Microphone; }); -define('Tone/source/Noise',["Tone/core/Tone", "Tone/source/Source"], function(Tone){ - - - - /** - * @class Noise generator. - * Uses looped noise buffers to save on performance. - * - * @constructor - * @extends {Tone.Source} - * @param {string} type the noise type (white|pink|brown) - */ - Tone.Noise = function(type){ - - Tone.Source.call(this); - - /** - * @private - * @type {AudioBufferSourceNode} - */ - this._source = null; - - /** - * the buffer - * @private - * @type {AudioBuffer} - */ - this._buffer = null; - - /** - * set a callback function to invoke when the sample is over - * - * @type {function} - */ - this.onended = function(){}; - - this.setType(this.defaultArg(type, "white")); - }; - - Tone.extend(Tone.Noise, Tone.Source); - - /** - * set the noise type - * - * @param {string} type the noise type (white|pink|brown) - * @param {Tone.Time} time (optional) time that the set will occur - */ - Tone.Noise.prototype.setType = function(type, time){ - switch (type){ - case "white" : - this._buffer = _whiteNoise; - break; - case "pink" : - this._buffer = _pinkNoise; - break; - case "brown" : - this._buffer = _brownNoise; - break; - default : - this._buffer = _whiteNoise; - } - //if it's playing, stop and restart it - if (this.state === Tone.Source.State.STARTED){ - time = this.toSeconds(time); - //remove the listener - this._source.onended = undefined; - this._stop(time); - this._start(time); - } - }; - - /** - * internal start method - * - * @param {Tone.Time} time - * @private - */ - Tone.Noise.prototype._start = function(time){ - this._source = this.context.createBufferSource(); - this._source.buffer = this._buffer; - this._source.loop = true; - this.chain(this._source, this.output); - this._source.start(this.toSeconds(time)); - this._source.onended = this._onended.bind(this); - }; - - /** - * start the noise at a specific time - * - * @param {Tone.Time} time - */ - Tone.Noise.prototype.start = function(time){ - if (this.state === Tone.Source.State.STOPPED){ - this.state = Tone.Source.State.STARTED; - //make the source - this._start(time); - } - }; - - /** - * internal stop method - * - * @param {Tone.Time} time - * @private - */ - Tone.Noise.prototype._stop = function(time){ - this._source.stop(this.toSeconds(time)); - }; - - - /** - * stop the noise at a specific time - * - * @param {Tone.Time} time - */ - Tone.Noise.prototype.stop = function(time){ - if (this.state === Tone.Source.State.STARTED) { - if (this._buffer && this._source){ - if (!time){ - this.state = Tone.Source.State.STOPPED; - } - this._stop(time); - } - } - }; - - /** - * internal call when the buffer is done playing - * - * @private - */ - Tone.Noise.prototype._onended = function(){ - this.state = Tone.Source.State.STOPPED; - this.onended(); - }; - - /** - * dispose all the components - */ - Tone.Noise.prototype.dispose = function(){ - Tone.Source.prototype.dispose.call(this); - if (this._source !== null){ - this._source.disconnect(); - this._source = null; - } - this._buffer = null; - }; - - - /////////////////////////////////////////////////////////////////////////// - // THE BUFFERS - // borred heavily from http://noisehack.com/generate-noise-web-audio-api/ - /////////////////////////////////////////////////////////////////////////// - - /** - * static noise buffers - * - * @static - * @private - * @type {AudioBuffer} - */ - var _pinkNoise = null, _brownNoise = null, _whiteNoise = null; - - Tone._initAudioContext(function(audioContext){ - - var sampleRate = audioContext.sampleRate; - - //four seconds per buffer - var bufferLength = sampleRate * 4; - - //fill the buffers - _pinkNoise = (function() { - var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); - for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++){ - var channel = buffer.getChannelData(channelNum); - var b0, b1, b2, b3, b4, b5, b6; - b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0; - for (var i = 0; i < bufferLength; i++) { - var white = Math.random() * 2 - 1; - b0 = 0.99886 * b0 + white * 0.0555179; - b1 = 0.99332 * b1 + white * 0.0750759; - b2 = 0.96900 * b2 + white * 0.1538520; - b3 = 0.86650 * b3 + white * 0.3104856; - b4 = 0.55000 * b4 + white * 0.5329522; - b5 = -0.7616 * b5 - white * 0.0168980; - channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; - channel[i] *= 0.11; // (roughly) compensate for gain - b6 = white * 0.115926; - } - } - return buffer; - }()); - - _brownNoise = (function() { - var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); - for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++){ - var channel = buffer.getChannelData(channelNum); - var lastOut = 0.0; - for (var i = 0; i < bufferLength; i++) { - var white = Math.random() * 2 - 1; - channel[i] = (lastOut + (0.02 * white)) / 1.02; - lastOut = channel[i]; - channel[i] *= 3.5; // (roughly) compensate for gain - } - } - return buffer; - })(); - - _whiteNoise = (function(){ - var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); - for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++){ - var channel = buffer.getChannelData(channelNum); - for (var i = 0; i < bufferLength; i++){ - channel[i] = Math.random() * 2 - 1; - } - } - return buffer; - }()); - }); - - return Tone.Noise; -}); define('Tone/source/PulseOscillator',["Tone/core/Tone", "Tone/source/Source", "Tone/source/Oscillator", "Tone/signal/Signal", "Tone/signal/Threshold"], function(Tone){ diff --git a/build/Tone.min.js b/build/Tone.min.js index e1334eac..8837f707 100644 --- a/build/Tone.min.js +++ b/build/Tone.min.js @@ -6,6 +6,7 @@ * @license http://opensource.org/licenses/MIT MIT License 2014 */ -!function(t){"function"!=typeof define&&"function"!=typeof t.Tone&&(t.define=function(){var e=arguments[arguments.length-1],i=arguments[0];"Tone/core/Tone"===i?t.Tone=e():"function"==typeof e&&e(t.Tone)})}(this),define("Tone/core/Tone",[],function(){function t(t){return void 0===t}var e;if(t(window.AudioContext)&&(window.AudioContext=window.webkitAudioContext),t(window.OfflineAudioContext)&&(window.OfflineAudioContext=window.webkitOfflineAudioContext),t(AudioContext))throw new Error("Web Audio is not supported in this browser");e=new AudioContext,"function"!=typeof AudioContext.prototype.createGain&&(AudioContext.prototype.createGain=AudioContext.prototype.createGainNode),"function"!=typeof AudioContext.prototype.createDelay&&(AudioContext.prototype.createDelay=AudioContext.prototype.createDelayNode),"function"!=typeof AudioContext.prototype.createPeriodicWave&&(AudioContext.prototype.createPeriodicWave=AudioContext.prototype.createWaveTable),"function"!=typeof AudioBufferSourceNode.prototype.start&&(AudioBufferSourceNode.prototype.start=AudioBufferSourceNode.prototype.noteGrainOn),"function"!=typeof AudioBufferSourceNode.prototype.stop&&(AudioBufferSourceNode.prototype.stop=AudioBufferSourceNode.prototype.noteOff),"function"!=typeof OscillatorNode.prototype.start&&(OscillatorNode.prototype.start=OscillatorNode.prototype.noteOn),"function"!=typeof OscillatorNode.prototype.stop&&(OscillatorNode.prototype.stop=OscillatorNode.prototype.noteOff),"function"!=typeof OscillatorNode.prototype.setPeriodicWave&&(OscillatorNode.prototype.setPeriodicWave=OscillatorNode.prototype.setWaveTable),AudioNode.prototype._nativeConnect=AudioNode.prototype.connect,AudioNode.prototype.connect=function(e,i,o){if(e.input)Array.isArray(e.input)?(t(o)&&(o=0),this.connect(e.input[o])):this.connect(e.input);else try{e instanceof AudioNode?this._nativeConnect(e,i,o):this._nativeConnect(e,i)}catch(n){throw new Error("error connecting to node: "+e)}};var i=function(){this.input=this.context.createGain(),this.output=this.context.createGain()};i.context=e,i.prototype.context=i.context,i.prototype.bufferSize=2048,i.prototype.connect=function(t,e,i){Array.isArray(this.output)?(e=this.defaultArg(e,0),this.output[e].connect(t,0,i)):this.output.connect(t,e,i)},i.prototype.disconnect=function(){this.output.disconnect()},i.prototype.chain=function(){if(arguments.length>1)for(var t=arguments[0],e=1;e1)for(var e=1;ei){var o=i;i=e,e=o}else if(e==i)return 0;return(t-e)/(i-e)},i.prototype.dispose=function(){this.isUndef(this.input)||(this.input instanceof AudioNode&&this.input.disconnect(),this.input=null),this.isUndef(this.output)||(this.output instanceof AudioNode&&this.output.disconnect(),this.output=null)};var o=null;i.prototype.noGC=function(){this.output.connect(o)},AudioNode.prototype.noGC=function(){this.connect(o)},i.prototype.now=function(){return this.context.currentTime},i.prototype.samplesToSeconds=function(t){return t/this.context.sampleRate},i.prototype.toSamples=function(t){var e=this.toSeconds(t);return Math.round(e*this.context.sampleRate)},i.prototype.toSeconds=function(t,e){if(e=this.defaultArg(e,this.now()),"number"==typeof t)return t;if("string"==typeof t){var i=0;return"+"===t.charAt(0)&&(t=t.slice(1),i=e),parseFloat(t)+i}return e},i.prototype.frequencyToSeconds=function(t){return 1/parseFloat(t)},i.prototype.secondsToFrequency=function(t){return 1/t};var n=[];return i._initAudioContext=function(t){t(i.context),n.push(t)},i.setContext=function(t){i.prototype.context=t,i.context=t;for(var e=0;es;s++)n[s]=1;i.curve=n,e.connect(i),e.start(0),e.noGC()}),t.Signal}),define("Tone/signal/Add",["Tone/core/Tone","Tone/signal/Signal"],function(t){return t.Add=function(e){this._value=new t.Signal(e),this.input=this.output=this.context.createGain(),this._value.connect(this.output)},t.extend(t.Add),t.Add.prototype.setValue=function(t){this._value.setValue(t)},t.Add.prototype.connect=t.Signal.prototype.connect,t.Add.prototype.dispose=function(){t.prototype.dispose.call(this),this._value.dispose(),this._value=null},t.Add}),define("Tone/signal/Multiply",["Tone/core/Tone","Tone/signal/Signal"],function(t){return t.Multiply=function(t){this.input=this.output=this.context.createGain(),this.input.gain.value=this.defaultArg(t,1)},t.extend(t.Multiply),t.Multiply.prototype.setValue=function(t){this.input.gain.value=t},t.Multiply.prototype.connect=t.Signal.prototype.connect,t.Multiply.prototype.dispose=function(){t.prototype.dispose.call(this)},t.Multiply}),define("Tone/signal/Scale",["Tone/core/Tone","Tone/signal/Add","Tone/signal/Multiply","Tone/signal/Signal"],function(t){return t.Scale=function(e,i,o,n){t.call(this),2==arguments.length&&(o=e,n=i,e=-1,i=1),this._inputMin=e,this._inputMax=i,this._outputMin=o,this._outputMax=n,this._plusInput=new t.Add(0),this._scale=new t.Multiply(1),this._plusOutput=new t.Add(0),this.chain(this.input,this._plusInput,this._scale,this._plusOutput,this.output),this._setScalingParameters()},t.extend(t.Scale),t.Scale.prototype._setScalingParameters=function(){this._plusInput.setValue(-this._inputMin),this._scale.setValue((this._outputMax-this._outputMin)/(this._inputMax-this._inputMin)),this._plusOutput.setValue(this._outputMin)},t.Scale.prototype.setInputMin=function(t){this._inputMin=t,this._setScalingParameters()},t.Scale.prototype.setInputMax=function(t){this._inputMax=t,this._setScalingParameters()},t.Scale.prototype.setOutputMin=function(t){this._outputMin=t,this._setScalingParameters()},t.Scale.prototype.setOutputMax=function(t){this._outputMax=t,this._setScalingParameters()},t.Scale.prototype.connect=t.Signal.prototype.connect,t.Scale.prototype.dispose=function(){t.prototype.dispose.call(this),this._plusInput.dispose(),this._plusOutput.dispose(),this._scale.dispose(),this._plusInput=null,this._plusOutput=null,this._scale=null},t.Scale}),define("Tone/component/DryWet",["Tone/core/Tone","Tone/signal/Signal","Tone/signal/Scale"],function(t){return t.DryWet=function(e){t.call(this),this.dry=this.input,this.wet=this.context.createGain(),this.wetness=new t.Signal,this._invert=new t.Scale(0,1,1,0),this.dry.connect(this.output),this.wet.connect(this.output),this.chain(this.wetness,this.wet.gain),this.chain(this.wetness,this._invert,this.dry.gain),this.setDry(this.defaultArg(e,0))},t.extend(t.DryWet),t.DryWet.prototype.setDry=function(t,e){this.setWet(1-t,e)},t.DryWet.prototype.setWet=function(t,e){e?this.wetness.linearRampToValueNow(t,e):this.wetness.setValue(t)},t.DryWet.prototype.dispose=function(){t.prototype.dispose.call(this),this.dry.disconnect(),this.wet.disconnect(),this.wetness.dispose(),this._invert.dispose(),this.dry=null,this.wet=null,this.wetness=null,this._invert=null},t.DryWet}),define("Tone/component/Filter",["Tone/core/Tone","Tone/signal/Signal"],function(t){return t.Filter=function(){t.call(this);var e=this.optionsObject(arguments,["frequency","type","rolloff"],t.Filter.defaults);this._filters=[],this.frequency=new t.Signal(e.frequency),this.detune=new t.Signal(0),this.gain=new t.Signal(e.gain),this.Q=new t.Signal(e.Q),this._type=e.type,this.setRolloff(e.rolloff)},t.extend(t.Filter),t.Filter.defaults={type:"lowpass",frequency:350,rolloff:-12,Q:1,gain:0},t.Filter.prototype.set=function(t){this.isUndef(t.type)||this.setType(t.type),this.isUndef(t.detune)||this.detune.setValue(t.detune),this.isUndef(t.frequency)||this.frequency.setValue(t.frequency),this.isUndef(t.Q)||this.Q.setValue(t.Q),this.isUndef(t.gain)||this.gain.setValue(t.gain),this.isUndef(t.rolloff)||this.setRolloff(t.rolloff)},t.Filter.prototype.setType=function(t){this._type=t;for(var e=0;eo;o++){var n=this.context.createBiquadFilter();n.type=this._type,this.frequency.connect(n.frequency),this.detune.connect(n.detune),this.Q.connect(n.Q),this.gain.connect(n.gain),this._filters[o]=n}var s=[this.input].concat(this._filters).concat([this.output]);this.chain.apply(this,s)},t.Filter.prototype.dispose=function(){t.prototype.dispose.call(this);for(var e=0;en;n++){var s,r=n/(i-1)*2-1;s=e>r?0:1,o[n]=s}t.curve=o},t.Threshold.prototype.setThreshold=function(t){this._setThresh(this._thresh,t)},t.Threshold.prototype.connect=t.Signal.prototype.connect,t.Threshold.prototype.dispose=function(){t.prototype.dispose.call(this),this._thresh.disconnect(),this._doubleThresh.disconnect(),this._thresh=null,this._doubleThresh=null},t.Threshold}),define("Tone/signal/EqualZero",["Tone/core/Tone","Tone/signal/Threshold","Tone/signal/Signal"],function(t){return t.EqualZero=function(){this._equals=this.context.createWaveShaper(),this._thresh=new t.Threshold(1),this.input=this._equals,this._equals.connect(this._thresh),this.output=this._thresh,this._setEquals()},t.extend(t.EqualZero),t.EqualZero.prototype._setEquals=function(){for(var t=1023,e=new Float32Array(t),i=0;t>i;i++){var o=i/(t-1)*2-1;e[i]=0===o?1:0}this._equals.curve=e},t.EqualZero.prototype.connect=t.Signal.prototype.connect,t.EqualZero.prototype.dispose=function(){t.prototype.dispose.call(this),this._equals.disconnect(),this._thresh.dispose(),this._equals=null,this._thresh=null},t.EqualZero}),define("Tone/signal/Equal",["Tone/core/Tone","Tone/signal/EqualZero","Tone/signal/Add","Tone/signal/Signal"],function(t){return t.Equal=function(e){this._adder=new t.Add(-e),this._equals=new t.EqualZero,this.input=this._adder,this.output=this._equals,this._adder.connect(this._equals)},t.extend(t.Equal),t.Equal.prototype.setValue=function(t){this._adder.setValue(-t)},t.Equal.prototype.connect=t.Signal.prototype.connect,t.Equal.prototype.dispose=function(){t.prototype.dispose.call(this),this._equals.disconnect(),this._adder.dispose(),this._equals=null,this._adder=null},t.Equal}),define("Tone/signal/Select",["Tone/core/Tone","Tone/signal/Equal","Tone/signal/Signal"],function(t){t.Select=function(i){i=this.defaultArg(i,2),this.input=new Array(i),this.output=this.context.createGain(),this.gate=new t.Signal(0);for(var o=0;i>o;o++){var n=new e(o);this.input[o]=n,this.gate.connect(n.selecter),n.connect(this.output)}},t.extend(t.Select),t.Select.prototype.select=function(t,e){t=Math.floor(t),this.gate.setValueAtTime(t,this.toSeconds(e))},t.Select.prototype.connect=t.Signal.prototype.connect,t.Select.prototype.dispose=function(){this.gate.dispose();for(var e=0;en;n++){var s,r=n/(i-1)*2-1;s=0>=r?t:e,o[n]=s}this._frequencyValues.curve=o},t.Follower.prototype.setAttack=function(t){this._attack=this.secondsToFrequency(t),this._setAttackRelease(this._attack,this._release)},t.Follower.prototype.setRelease=function(t){this._release=this.secondsToFrequency(t),this._setAttackRelease(this._attack,this._release)},t.Follower.prototype.set=function(e){this.isUndef(e.attack)||this.setAttack(e.attack),this.isUndef(e.release)||this.setRelease(e.release),t.Effect.prototype.set.call(this,e)},t.Follower.prototype.connect=t.Signal.prototype.connect,t.Follower.prototype.dispose=function(){t.prototype.dispose.call(this),this._filter.disconnect(),this._frequencyValues.disconnect(),this._delay.disconnect(),this._difference.disconnect(),this._abs.dispose(),this._negate.dispose(),this._mult.dispose(),this._filter=null,this._delay=null,this._frequencyValues=null,this._abs=null,this._negate=null,this._difference=null,this._mult=null},t.Follower}),define("Tone/signal/GreaterThan",["Tone/core/Tone","Tone/signal/LessThan","Tone/signal/Negate","Tone/signal/Signal"],function(t){return t.GreaterThan=function(e){this._lt=new t.LessThan(-e),this._neg=new t.Negate,this.input=this._neg,this.output=this._lt,this._neg.connect(this._lt)},t.extend(t.GreaterThan),t.GreaterThan.prototype.setValue=function(t){this._lt.setValue(-t)},t.GreaterThan.prototype.connect=t.Signal.prototype.connect,t.GreaterThan.prototype.dispose=function(){t.prototype.dispose.call(this),this._lt.disconnect(),this._neg.disconnect(),this._lt=null,this._neg=null},t.GreaterThan}),define("Tone/component/Gate",["Tone/core/Tone","Tone/component/Follower","Tone/signal/GreaterThan"],function(t){return t.Gate=function(e,i,o){t.call(this),e=this.defaultArg(e,-40),i=this.defaultArg(i,.1),o=this.defaultArg(o,.2),this._follower=new t.Follower(i,o),this._gt=new t.GreaterThan(this.dbToGain(e)),this.chain(this.input,this.output),this.chain(this.input,this._gt,this._follower,this.output.gain)},t.extend(t.Gate),t.Gate.prototype.setThreshold=function(t){this._gt.setValue(this.dbToGain(t))},t.Gate.prototype.setAttack=function(t){this._follower.setAttack(t)},t.Gate.prototype.setRelease=function(t){this._follower.setRelease(t)},t.Gate.prototype.dispose=function(){t.prototype.dispose.call(this),this._follower.dispose(),this._gt.dispose(),this._follower=null,this._gt=null},t.Gate}),define("Tone/core/Clock",["Tone/core/Tone","Tone/signal/Signal"],function(t){return t.Clock=function(e,i){this._oscillator=null,this._jsNode=this.context.createScriptProcessor(this.bufferSize,1,1),this._jsNode.onaudioprocess=this._processBuffer.bind(this),this._controlSignal=new t.Signal(1),this._upTick=!1,this.tick=this.defaultArg(i,function(){}),this._jsNode.noGC(),this.setRate(e)},t.extend(t.Clock),t.Clock.prototype.setRate=function(t,e){var i=this.secondsToFrequency(this.toSeconds(t));e?this._controlSignal.exponentialRampToValueNow(i,e):(this._controlSignal.cancelScheduledValues(0),this._controlSignal.setValue(i))},t.Clock.prototype.getRate=function(){return this._controlSignal.getValue()},t.Clock.prototype.start=function(t){this._oscillator=this.context.createOscillator(),this._oscillator.type="square",this._oscillator.connect(this._jsNode),this._controlSignal.connect(this._oscillator.frequency),this._upTick=!1;var e=this.toSeconds(t);this._oscillator.start(e)},t.Clock.prototype.stop=function(t){var e=this.toSeconds(t);this._oscillator.stop(e)},t.Clock.prototype._processBuffer=function(t){for(var e=this.defaultArg(t.playbackTime,this.now()),i=this._jsNode.bufferSize,o=t.inputBuffer.getChannelData(0),n=this._upTick,s=0;i>s;s++){var r=o[s];r>0&&!n?(n=!0,this.tick(e+this.samplesToSeconds(s))):0>r&&n&&(n=!1)}this._upTick=n},t.Clock.prototype.dispose=function(){this._jsNode.disconnect(),this._controlSignal.dispose(),this._oscillator&&this._oscillator.disconnect(),this._jsNode.onaudioprocess=function(){},this._jsNode=null,this._controlSignal=null,this._oscillator=null},t.Clock}),define("Tone/core/Transport",["Tone/core/Tone","Tone/core/Clock","Tone/signal/Signal"],function(Tone){Tone.Transport=function(){this._clock=new Tone.Clock(1,this._processTick.bind(this)),this.loop=!1,this.state=TransportState.STOPPED},Tone.extend(Tone.Transport);var timelineTicks=0,transportTicks=0,tatum=12,transportTimeSignature=4,loopStart=0,loopEnd=4*tatum,intervals=[],timeouts=[],transportTimeline=[],timelineProgress=0,SyncedSources=[],TransportState={STARTED:"started",PAUSED:"paused",STOPPED:"stopped"};Tone.Transport.prototype._processTick=function(t){processIntervals(t),processTimeouts(t),processTimeline(t),transportTicks+=1,timelineTicks+=1,this.loop&&timelineTicks===loopEnd&&this._setTicks(loopStart)},Tone.Transport.prototype._setTicks=function(t){timelineTicks=t;for(var e=0;e=t){timelineProgress=e;break}}};var processIntervals=function(t){for(var e=0,i=intervals.length;i>e;e++){var o=intervals[e];o.testInterval(transportTicks)&&o.doCallback(t)}},processTimeouts=function(t){for(var e=0,i=0,o=timeouts.length;o>i;i++){var n=timeouts[i],s=n.callbackTick();if(transportTicks>=s)n.doCallback(t),e++;else if(s>transportTicks)break}timeouts.splice(0,e)},processTimeline=function(t){for(var e=timelineProgress,i=transportTimeline.length;i>e;e++){var o=transportTimeline[e],n=o.callbackTick();if(n===timelineTicks)o.doCallback(t),timelineProgress=e;else if(n>timelineTicks)break}};Tone.Transport.prototype.setInterval=function(t,e,i){var o=this.toTicks(e),n=new TimelineEvent(t,i,o,transportTicks);return intervals.push(n),n.id},Tone.Transport.prototype.clearInterval=function(t){for(var e=0;es;s++){var a=timeouts[s];if(a.callbackTick()>n.callbackTick())return timeouts.splice(s,0,n),n.id}return timeouts.push(n),n.id},Tone.Transport.prototype.clearTimeout=function(t){for(var e=0;es;s++){var a=transportTimeline[s];if(a.callbackTick()>n.callbackTick())return transportTimeline.splice(s,0,n),n.id}return transportTimeline.push(n),n.id},Tone.Transport.prototype.clearTimeline=function(t){for(var e=0;e1){for(var oringalTime=time,i=0;ir;++r){var a,c=2/(r*Math.PI);switch(t){case"sine":a=1===r?1:0;break;case"square":a=1&r?2*c:0;break;case"sawtooth":a=c*(1&r?1:-1);break;case"triangle":a=1&r?2*c*c*(r-1>>1&1?-1:1):0;break;default:throw new TypeError("invalid oscillator type: "+t)}0!==a?(o[r]=-a*Math.sin(s),n[r]=a*Math.cos(s)):(o[r]=0,n[r]=0)}var h=this.context.createPeriodicWave(o,n);this._wave=h,this.oscillator.setPeriodicWave(this._wave),this._type=t},t.Oscillator.prototype.getType=function(){return this._type},t.Oscillator.prototype.setPhase=function(t){this._phase=t*Math.PI/180,this.setType(this._type)},t.Oscillator.prototype.set=function(t){this.isUndef(t.type)||this.setType(t.type),this.isUndef(t.phase)||this.setPhase(t.phase),this.isUndef(t.frequency)||this.frequency.setValue(t.frequency),this.isUndef(t.onended)||(this.onended=t.onended),this.isUndef(t.detune)||this.detune.setValue(t.detune)},t.Oscillator.prototype._onended=function(){this.state=t.Source.State.STOPPED,this.onended()},t.Oscillator.prototype.dispose=function(){t.Source.prototype.dispose.call(this),this.stop(),null!==this.oscillator&&(this.oscillator.disconnect(),this.oscillator=null),this.frequency.dispose(),this.detune.dispose(),this._wave=null,this.detune=null,this.frequency=null},t.Oscillator}),define("Tone/component/LFO",["Tone/core/Tone","Tone/source/Oscillator","Tone/signal/Scale","Tone/signal/Signal"],function(t){return t.LFO=function(e,i,o){this.oscillator=new t.Oscillator(this.defaultArg(e,1),"sine"),this.frequency=this.oscillator.frequency,this._scaler=new t.Scale(this.defaultArg(i,0),this.defaultArg(o,1)),this.output=this._scaler,this.chain(this.oscillator,this.output)},t.extend(t.LFO),t.LFO.prototype.start=function(t){this.oscillator.start(t)},t.LFO.prototype.stop=function(t){this.oscillator.stop(t)},t.LFO.prototype.sync=function(e){t.Transport.syncSource(this.oscillator,e),t.Transport.syncSignal(this.oscillator.frequency)},t.LFO.prototype.unsync=function(){t.Transport.unsyncSource(this.oscillator),t.Transport.unsyncSignal(this.oscillator.frequency)},t.LFO.prototype.setFrequency=function(t){this.oscillator.setFrequency(t)},t.LFO.prototype.setPhase=function(t){this.oscillator.setPhase(t)},t.LFO.prototype.setMin=function(t){this._scaler.setOutputMin(t)},t.LFO.prototype.setMax=function(t){this._scaler.setOutputMax(t)},t.LFO.prototype.setType=function(t){this.oscillator.setType(t)},t.LFO.prototype.set=function(t){this.isUndef(t.frequency)||this.setFrequency(t.frequency),this.isUndef(t.type)||this.setType(t.type),this.isUndef(t.min)||this.setMin(t.min),this.isUndef(t.max)||this.setMax(t.max)},t.LFO.prototype.connect=t.Signal.prototype.connect,t.LFO.prototype.dispose=function(){t.prototype.dispose.call(this),this.oscillator.dispose(),this._scaler.dispose(),this._scaler=null,this.oscillator=null,this.frequency=null},t.LFO}),define("Tone/component/Merge",["Tone/core/Tone"],function(t){return t.Merge=function(){this.output=this.context.createGain(),this.input=new Array(2),this.left=this.input[0]=this.context.createGain(),this.right=this.input[1]=this.context.createGain(),this._merger=this.context.createChannelMerger(2),this.left.connect(this._merger,0,0),this.right.connect(this._merger,0,1),this._merger.connect(this.output)},t.extend(t.Merge),t.Merge.prototype.dispose=function(){t.prototype.dispose.call(this),this.left.disconnect(),this.right.disconnect(),this._merger.disconnect(),this.left=null,this.right=null,this._merger=null},t.Merge}),define("Tone/core/Master",["Tone/core/Tone"],function(t){t.Master=function(){t.call(this),this.limiter=this.context.createDynamicsCompressor(),this.limiter.threshold.value=0,this.limiter.ratio.value=20,this.chain(this.input,this.limiter,this.output,this.context.destination)},t.extend(t.Master),t.Master.prototype.mute=function(t){t=this.defaultArg(t,!0),this.output.gain.value=t?0:1},t.Master.prototype.setVolume=function(t,e){var i=this.now(),o=this.dbToGain(t);if(e){var n=this.output.gain.value;this.output.gain.cancelScheduledValues(i),this.output.gain.setValueAtTime(n,i),this.output.gain.linearRampToValueAtTime(o,i+this.toSeconds(e))}else this.output.gain.setValueAtTime(o,i)},t.prototype.toMaster=function(){this.connect(t.Master)},AudioNode.prototype.toMaster=function(){this.connect(t.Master)};var e=t.Master;return t.Master=new t.Master,t._initAudioContext(function(){e.call(t.Master)}),t.Master}),define("Tone/component/Meter",["Tone/core/Tone","Tone/core/Master"],function(t){return t.Meter=function(e,i,o){t.call(this),this.channels=this.defaultArg(e,1),this.smoothing=this.defaultArg(i,.8),this.clipMemory=this.defaultArg(o,500),this._volume=new Array(this.channels),this._values=new Array(this.channels);for(var n=0;nh;h++)n=s[h],!c&&n>.95&&(c=!0,this._lastClip=Date.now()),a+=n,r+=n*n;var l=a/e,u=Math.sqrt(r/e);this._volume[o]=Math.max(u,this._volume[o]*i),this._values[o]=l}},t.Meter.prototype.getLevel=function(t){t=this.defaultArg(t,0);var e=this._volume[t];return 1e-5>e?0:e},t.Meter.prototype.getValue=function(t){return t=this.defaultArg(t,0),this._values[t]},t.Meter.prototype.getDb=function(t){return this.gainToDb(this.getLevel(t))},t.Meter.prototype.isClipped=function(){return Date.now()-this._lastClipthis._recordEndSample?(this.state=e.STOPPED,this._callback(this._recordBuffers)):s>this._recordStartSample?(i=0,o=Math.min(this._recordEndSample-s,r),this._recordChannels(t.inputBuffer,i,o,r)):a>this._recordStartSample&&(o=a-this._recordStartSample,i=r-o,this._recordChannels(t.inputBuffer,i,o,r))}},t.Recorder.prototype._recordChannels=function(t,e,i,o){for(var n=this._recordBufferOffset,s=this._recordBuffers,r=0;rc;c++){var h=c-e;s[r][h+n]=a[c]}}this._recordBufferOffset+=i},t.Recorder.prototype.record=function(t,i,o){if(this.state===e.STOPPED){this.clear(),this._recordBufferOffset=0,i=this.defaultArg(i,0),this._recordDuration=this.toSamples(t),this._recordStartSample=this.toSamples("+"+i),this._recordEndSample=this._recordStartSample+this._recordDuration;for(var n=0;ns;s++){var a=n[s];Array.isArray(o)?a.apply(window,[e].concat(o)):a(e,o)}}t.Note=function(e,i,o){this.value=o,this._channel=e,this._timelineID=t.Transport.setTimeline(this._trigger.bind(this),i)},t.Note.prototype._trigger=function(t){e(this._channel,t,this.value)},t.Note.prototype.dispose=function(){t.Tranport.clearTimeline(this._timelineID),this.value=null};var i={};t.Note.route=function(t,e){i.hasOwnProperty(t)?i[t].push(e):i[t]=[e]},t.Note.unroute=function(t,e){if(i.hasOwnProperty(t)){var o=i[t],n=o.indexOf(e);-1!==n&&i[t].splice(n,1)}},t.Note.parseScore=function(e){var i=[];for(var o in e){var n=e[o];if(!Array.isArray(n))throw new TypeError("score parts must be Arrays");for(var s=0;so;o++){var n=o/e*2-1;i[o]=n>=0?Math.pow(n,t):n}this._expScaler.curve=i},t.ScaleExp.prototype.setInputMin=function(t){this._inputMin=t,this._setScalingParameters()},t.ScaleExp.prototype.setInputMax=function(t){this._inputMax=t,this._setScalingParameters()},t.ScaleExp.prototype.setOutputMin=function(t){this._outputMin=t,this._setScalingParameters()},t.ScaleExp.prototype.setOutputMax=function(t){this._outputMax=t,this._setScalingParameters()},t.ScaleExp.prototype.connect=t.Signal.prototype.connect,t.ScaleExp.prototype.dispose=function(){t.prototype.dispose.call(this),this._plusInput.dispose(),this._plusOutput.dispose(),this._normalize.dispose(),this._scale.dispose(),this._expScaler.disconnect(),this._plusInput=null,this._plusOutput=null,this._scale=null,this._normalize=null,this._expScaler=null},t.ScaleExp}),define("Tone/effect/AutoWah",["Tone/core/Tone","Tone/component/Follower","Tone/signal/ScaleExp","Tone/effect/Effect"],function(t){return t.AutoWah=function(){var e=this.optionsObject(arguments,["baseFrequency","octaves","sensitivity"],t.AutoWah.defaults);t.Effect.call(this,e),this._follower=new t.Follower(e.follower),this._sweepRange=new t.ScaleExp(0,1,0,1,.5),this._baseFrequency=e.baseFrequency,this._octaves=e.octaves,this._bandpass=new t.Filter(0,"bandpass"),this._bandpass.setRolloff(e.rolloff),this._peaking=this.context.createBiquadFilter(),this._peaking.type="peaking",this._peaking.gain.value=e.gain,this.chain(this.effectSend,this._follower,this._sweepRange),this._sweepRange.connect(this._bandpass.frequency),this._sweepRange.connect(this._peaking.frequency),this.chain(this.effectSend,this._bandpass,this._peaking,this.effectReturn),this._setSweepRange(),this.setSensitiviy(e.sensitivity)},t.extend(t.AutoWah,t.Effect),t.AutoWah.defaults={baseFrequency:100,octaves:6,sensitivity:0,Q:2,gain:2,rolloff:-48,follower:{attack:.3,release:.5}},t.AutoWah.prototype.setOctaves=function(t){this._octaves=t,this._setSweepRange()},t.AutoWah.prototype.setBaseFrequency=function(t){this._baseFrequency=t,this._setSweepRange()},t.AutoWah.prototype.setSensitiviy=function(t){this._sweepRange.setInputMax(this.dbToGain(t))},t.AutoWah.prototype._setSweepRange=function(){this._sweepRange.setOutputMin(this._baseFrequency),this._sweepRange.setOutputMax(Math.min(this._baseFrequency*Math.pow(2,this._octaves),this.context.sampleRate/2))},t.AutoWah.prototype.set=function(e){this.isUndef(e.baseFrequency)||this.setBaseFrequency(e.baseFrequency),this.isUndef(e.sensitivity)||this.setSensitiviy(e.sensitivity),this.isUndef(e.octaves)||this.setOctaves(e.octaves),this.isUndef(e.follower)||this._follower.set(e.follower),this.isUndef(e.Q)||(this._bandpass.Q.value=e.Q),this.isUndef(e.gain)||(this._peaking.gain.value=e.gain),t.Effect.prototype.set.call(this,e)},t.AutoWah.prototype.dispose=function(){t.Effect.prototype.dispose.call(this),this._follower.dispose(),this._sweepRange.dispose(),this._bandpass.disconnect(),this._peaking.disconnect(),this._follower=null,this._sweepRange=null,this._bandpass=null,this._peaking=null},t.AutoWah}),define("Tone/signal/Modulo",["Tone/core/Tone","Tone/signal/LessThan","Tone/signal/Select","Tone/signal/Not"],function(t){t.Modulo=function(i,o){t.call(this),o=this.defaultArg(o,4),this._modChain=[];for(var n=o-1;n>=0;n--){var s=new e(i,Math.pow(2,n));this._modChain.push(s)}this.input.connect(this._modChain[0]),this.chain.apply(this,this._modChain),this._modChain[o-1].connect(this.output)},t.extend(t.Modulo),t.Modulo.prototype.dispose=function(){t.prototype.dispose.call(this);for(var e=0;en;n++){var s=this.context.createBiquadFilter();s.type="allpass",s.Q.value=i,e.connect(s.frequency),o[n]=s}return this.chain.apply(this,o),o},t.Phaser.prototype.setDepth=function(t){this._depth=t;var e=this._baseFrequency+this._baseFrequency*t;this._lfoL.setMax(e),this._lfoR.setMax(e)},t.Phaser.prototype.setBaseFrequency=function(t){this._baseFrequency=t,this._lfoL.setMin(t),this._lfoR.setMin(t),this.setDepth(this._depth)},t.Phaser.prototype.setRate=function(t){this._lfoL.setFrequency(t)},t.Phaser.prototype.set=function(e){this.isUndef(e.rate)||this.setRate(e.rate),this.isUndef(e.baseFrequency)||this.setBaseFrequency(e.baseFrequency),this.isUndef(e.depth)||this.setDepth(e.depth),t.StereoFeedbackEffect.prototype.set.call(this,e)},t.Phaser.prototype.dispose=function(){t.StereoFeedbackEffect.prototype.dispose.call(this),this._lfoL.dispose(),this._lfoR.dispose();for(var e=0;e0){var i=this.frequency.getValue();this.frequency.setValueAtTime(i,e),this.frequency.exponentialRampToValueAtTime(t,e+this.portamento)}else this.frequency.setValueAtTime(t,e)},t.Monophonic.prototype.setPortamento=function(t){this.portamento=this.toSeconds(t)},t.Monophonic.prototype.setVolume=t.Source.prototype.setVolume,t.Monophonic.prototype.set=function(t){this.isUndef(t.volume)||this.setVolume(t.volume),this.isUndef(t.portamento)||this.setPortamento(t.portamento)},t.Monophonic.prototype.setPreset=function(t){!this.isUndef(this.preset)&&this.preset.hasOwnProperty(t)&&this.set(this.preset[t])},t.Monophonic.prototype.dispose=function(){t.prototype.dispose.call(this)},t.Monophonic}),define("Tone/instrument/MonoSynth",["Tone/core/Tone","Tone/component/Envelope","Tone/source/Oscillator","Tone/signal/Signal","Tone/component/Filter","Tone/signal/Add","Tone/instrument/Monophonic"],function(t){return t.MonoSynth=function(e){e=this.defaultArg(e,t.MonoSynth.defaults),t.Monophonic.call(this,e),this.oscillator=new t.Oscillator(0,e.oscType),this.frequency=this.oscillator.frequency,this.detune=this.oscillator.detune,this.filter=new t.Filter(e.filter),this.filterEnvelope=new t.Envelope(e.filterEnvelope),this.envelope=new t.Envelope(e.envelope),this._amplitude=this.context.createGain(),this.oscillator.connect(this.filter),this.filter.connect(this._amplitude),this.oscillator.start(),this.filterEnvelope.connect(this.filter.frequency),this.envelope.connect(this._amplitude.gain),this._amplitude.connect(this.output)},t.extend(t.MonoSynth,t.Monophonic),t.MonoSynth.defaults={oscType:"square",filter:{Q:6,type:"lowpass",rolloff:-24},envelope:{attack:.005,decay:.1,sustain:.9,release:1},filterEnvelope:{attack:.06,decay:.2,sustain:.5,release:2,min:20,max:4e3}},t.MonoSynth.prototype.triggerEnvelopeAttack=function(t,e){this.envelope.triggerAttack(t,e),this.filterEnvelope.triggerAttack(t)},t.MonoSynth.prototype.triggerEnvelopeRelease=function(t){this.envelope.triggerRelease(t),this.filterEnvelope.triggerRelease(t)},t.MonoSynth.prototype.setOscType=function(t){this.oscillator.setType(t)},t.MonoSynth.prototype.set=function(e){this.isUndef(e.detune)||this.detune.setValue(e.detune),this.isUndef(e.oscType)||this.setOscType(e.oscType),this.isUndef(e.filterEnvelope)||this.filterEnvelope.set(e.filterEnvelope),this.isUndef(e.envelope)||this.envelope.set(e.envelope),this.isUndef(e.filter)||this.filter.set(e.filter),t.Monophonic.prototype.set.call(this,e)},t.MonoSynth.prototype.dispose=function(){t.Monophonic.prototype.dispose.call(this),this.oscillator.dispose(),this.envelope.dispose(),this.filterEnvelope.dispose(),this.filter.dispose(),this._amplitude.disconnect(),this.oscillator=null,this.filterEnvelope=null,this.envelope=null,this.filter=null,this.detune=null,this._amplitude=null,this.frequency=null,this.detune=null},t.MonoSynth}),define("Tone/instrument/DuoSynth",["Tone/core/Tone","Tone/instrument/MonoSynth","Tone/component/LFO","Tone/signal/Signal","Tone/signal/Multiply","Tone/instrument/Monophonic"],function(t){return t.DuoSynth=function(e){e=this.defaultArg(e,t.DuoSynth.defaults),t.Monophonic.call(this,e),this.voice0=new t.MonoSynth(e.voice0),this.voice0.setVolume(-10),this.voice1=new t.MonoSynth(e.voice1),this.voice1.setVolume(-10),this._vibrato=new t.LFO(e.vibratoRate,-50,50),this._vibrato.start(),this._vibratoGain=this.context.createGain(),this._vibratoGain.gain.value=e.vibratoAmount,this._vibratoDelay=this.toSeconds(e.vibratoDelay),this._vibratoAmount=e.vibratoAmount,this.frequency=new t.Signal(440),this._harmonicity=new t.Multiply(e.harmonicity),this.frequency.connect(this.voice0.frequency),this.chain(this.frequency,this._harmonicity,this.voice1.frequency),this._vibrato.connect(this._vibratoGain),this.fan(this._vibratoGain,this.voice0.detune,this.voice1.detune),this.voice0.connect(this.output),this.voice1.connect(this.output)},t.extend(t.DuoSynth,t.Monophonic),t.DuoSynth.defaults={vibratoAmount:.5,vibratoRate:5,vibratoDelay:1,harmonicity:1.5,voice0:{volume:-10,portamento:0,oscType:"sine",filterEnvelope:{attack:.01,decay:0,sustain:1,release:.5},envelope:{attack:.01,decay:0,sustain:1,release:.5}},voice1:{volume:-10,portamento:0,oscType:"sine",filterEnvelope:{attack:.01,decay:0,sustain:1,release:.5},envelope:{attack:.01,decay:0,sustain:1,release:.5}}},t.DuoSynth.prototype.triggerEnvelopeAttack=function(t,e){t=this.toSeconds(t),this.voice0.envelope.triggerAttack(t,e),this.voice1.envelope.triggerAttack(t,e),this.voice0.filterEnvelope.triggerAttack(t),this.voice1.filterEnvelope.triggerAttack(t)},t.DuoSynth.prototype.triggerEnvelopeRelease=function(t){this.voice0.triggerRelease(t),this.voice1.triggerRelease(t)},t.DuoSynth.prototype.setHarmonicity=function(t){this._harmonicity.setValue(t)},t.DuoSynth.prototype.setPortamento=function(t){this.portamento=this.toSeconds(t)},t.DuoSynth.prototype.setVibratoDelay=function(t){this._vibratoDelay=this.toSeconds(t)},t.DuoSynth.prototype.setVibratoAmount=function(t){this._vibratoAmount=t,this._vibratoGain.gain.setValueAtTime(t,this.now())},t.DuoSynth.prototype.setVibratoRate=function(t){this._vibrato.setFrequency(t)},t.DuoSynth.prototype.setVolume=t.Source.prototype.setVolume,t.DuoSynth.prototype.set=function(e){this.isUndef(e.harmonicity)||this.setHarmonicity(e.harmonicity),this.isUndef(e.vibratoRate)||this.setVibratoRate(e.vibratoRate),this.isUndef(e.vibratoAmount)||this.setVibratoAmount(e.vibratoAmount),this.isUndef(e.vibratoDelay)||this.setVibratoDelay(e.vibratoDelay),this.isUndef(e.voice0)||this.voice0.set(e.voice0),this.isUndef(e.voice1)||this.voice1.set(e.voice1),t.Monophonic.prototype.set.call(this,e)},t.DuoSynth.prototype.dispose=function(){t.Monophonic.prototype.dispose.call(this),this.voice0.dispose(),this.voice1.dispose(),this.frequency.dispose(),this._vibrato.dispose(),this._vibratoGain.disconnect(),this._harmonicity.dispose(),this.voice0=null,this.voice1=null,this.frequency=null,this._vibrato=null,this._vibratoGain=null,this._harmonicity=null},t.DuoSynth}),define("Tone/instrument/FMSynth",["Tone/core/Tone","Tone/instrument/MonoSynth","Tone/signal/Signal","Tone/signal/Multiply","Tone/instrument/Monophonic"],function(t){return t.FMSynth=function(e){e=this.defaultArg(e,t.FMSynth.defaults),t.Monophonic.call(this,e),this.carrier=new t.MonoSynth(e.carrier),this.carrier.setVolume(-10),this.modulator=new t.MonoSynth(e.modulator),this.modulator.setVolume(-10),this.frequency=new t.Signal(440),this._harmonicity=new t.Multiply(e.harmonicity),this._modulationIndex=new t.Multiply(e.modulationIndex),this._modulationNode=this.context.createGain(),this.frequency.connect(this.carrier.frequency),this.chain(this.frequency,this._harmonicity,this.modulator.frequency),this.chain(this.frequency,this._modulationIndex,this._modulationNode),this.modulator.connect(this._modulationNode.gain),this._modulationNode.gain.value=0,this._modulationNode.connect(this.carrier.frequency),this.carrier.connect(this.output)},t.extend(t.FMSynth,t.Monophonic),t.FMSynth.defaults={harmonicity:3,modulationIndex:10,carrier:{volume:-10,portamento:0,oscType:"sine",envelope:{attack:.01,decay:0,sustain:1,release:.5},filterEnvelope:{attack:.01,decay:0,sustain:1,release:.5,min:2e4,max:2e4}},modulator:{volume:-10,portamento:0,oscType:"triangle",envelope:{attack:.01,decay:0,sustain:1,release:.5},filterEnvelope:{attack:.01,decay:0,sustain:1,release:.5,min:2e4,max:2e4}}},t.FMSynth.prototype.triggerEnvelopeAttack=function(t,e){t=this.toSeconds(t),this.carrier.envelope.triggerAttack(t,e),this.modulator.envelope.triggerAttack(t),this.carrier.filterEnvelope.triggerAttack(t),this.modulator.filterEnvelope.triggerAttack(t)},t.FMSynth.prototype.triggerEnvelopeRelease=function(t){this.carrier.triggerRelease(t),this.modulator.triggerRelease(t)},t.FMSynth.prototype.setHarmonicity=function(t){this._harmonicity.setValue(t)},t.FMSynth.prototype.setModulationIndex=function(t){this._modulationIndex.setValue(t)},t.FMSynth.prototype.set=function(e){this.isUndef(e.harmonicity)||this.setHarmonicity(e.harmonicity),this.isUndef(e.modulationIndex)||this.setModulationIndex(e.modulationIndex),this.isUndef(e.carrier)||this.carrier.set(e.carrier),this.isUndef(e.modulator)||this.modulator.set(e.modulator),t.Monophonic.prototype.set.call(this,e)},t.FMSynth.prototype.dispose=function(){t.Monophonic.prototype.dispose.call(this),this.carrier.dispose(),this.modulator.dispose(),this.frequency.dispose(),this._modulationIndex.dispose(),this._harmonicity.dispose(),this._modulationNode.disconnect(),this.carrier=null,this.modulator=null,this.frequency=null,this._modulationIndex=null,this._harmonicity=null,this._modulationNode=null},t.FMSynth}),define("Tone/source/Player",["Tone/core/Tone","Tone/source/Source"],function(t){return t.Player=function(e,i){t.Source.call(this),this._source=null,this._buffer=null,this.duration=0,this.loop=!1,this.loopStart=0,this.loopEnd=0,this._playbackRate=1,this.retrigger=!1,this.onended=function(){},e&&this.load(e,i)},t.extend(t.Player,t.Source),t.Player.prototype.load=function(t,e){if(this._buffer)e&&e(this);else{var i=new XMLHttpRequest;i.open("GET",t,!0),i.responseType="arraybuffer";var o=this;i.onload=function(){o.context.decodeAudioData(i.response,function(t){o.setBuffer(t),e&&e(o)})},i.send()}},t.Player.prototype.setBuffer=function(t){this._buffer=t,this.duration=t.duration},t.Player.prototype.start=function(e,i,o){(this.state===t.Source.State.STOPPED||this.retrigger)&&this._buffer&&(this.state=t.Source.State.STARTED,i=this.defaultArg(i,0),this.loop&&(i=this.loopStart),o=this.defaultArg(o,this._buffer.duration-i),this._source=this.context.createBufferSource(),this._source.buffer=this._buffer,this._source.loop=this.loop,this._source.loopStart=this.loopStart,this._source.loopEnd=this.loopEnd,this._source.playbackRate.value=this._playbackRate,this._source.onended=this._onended.bind(this),this.chain(this._source,this.output),this._source.start(this.toSeconds(e),this.toSeconds(i),this.toSeconds(o)))},t.Player.prototype.stop=function(e){this.state===t.Source.State.STARTED&&this._buffer&&this._source&&(e||(this.state=t.Source.State.STOPPED),this._source.stop(this.toSeconds(e)))},t.Player.prototype.setPlaybackRate=function(t,e){this._playbackRate=t,this._source&&(e?this._source.playbackRate.exponentialRampToValueAtTime(t,this.toSeconds(e)):this._source.playbackRate.value=e)},t.Player.prototype._onended=function(){this.state=t.Source.State.STOPPED,this.onended()},t.Player.prototype.dispose=function(){t.Source.prototype.dispose.call(this),null!==this._source&&(this._source.disconnect(),this._source=null),this._buffer=null},t.Player}),define("Tone/instrument/Sampler",["Tone/core/Tone","Tone/source/Player","Tone/component/Envelope","Tone/component/Filter","Tone/source/Source"],function(t){return t.Sampler=function(){var e=this.optionsObject(arguments,["url","load"],t.Sampler.defaults);this.output=this.context.createGain(),this.player=new t.Player(e.url,e.load),this.player.retrigger=!0,this.envelope=new t.Envelope(e.envelope),this._amplitude=this.context.createGain(),this.filterEnvelope=new t.Envelope(e.filterEnvelope),this.filter=new t.Filter(e.filter),this.chain(this.player,this.filter,this._amplitude,this.output),this.envelope.connect(this._amplitude.gain),this.filterEnvelope.connect(this.filter.frequency)},t.extend(t.Sampler),t.Sampler.defaults={url:null,load:function(){},envelope:{attack:.001,decay:0,sustain:1,release:.1},filterEnvelope:{attack:.001,decay:.001,sustain:1,release:.5,min:20,max:2e4},filter:{type:"lowpass"}},t.Sampler.prototype.set=function(t){this.isUndef(t.filterEnvelope)||this.filterEnvelope.set(t.filterEnvelope),this.isUndef(t.envelope)||this.envelope.set(t.envelope),this.isUndef(t.filter)||this.filter.set(t.filter)},t.Sampler.prototype.triggerAttack=function(t,e){this.player.start(t),this.envelope.triggerAttack(t,e),this.filterEnvelope.triggerAttack(t)},t.Sampler.prototype.triggerRelease=function(t){this.filterEnvelope.triggerRelease(t),this.envelope.triggerRelease(t)},t.Sampler.prototype.triggerAttackRelease=function(t,e,i,o){i=this.toSeconds(i),this.triggerAttack(t,i,o),this.triggerRelease(i+this.toSeconds(e))},t.Sampler.prototype.setVolume=t.Source.prototype.setVolume,t.Sampler.prototype.dispose=function(){t.prototype.dispose.call(this),this.player.dispose(),this.filterEnvelope.dispose(),this.envelope.dispose(),this.filter.dispose(),this.player=null,this.filterEnvelope=null,this.envelope=null,this.filter=null},t.Sampler}),define("Tone/instrument/MultiSampler",["Tone/core/Tone","Tone/instrument/Sampler","Tone/source/Source"],function(t){return t.MultiSampler=function(t,e){this.output=this.context.createGain(),this.samples={},this._createSamples(t,e)},t.extend(t.MultiSampler),t.MultiSampler.prototype._createSamples=function(e,i){var o={total:0,loaded:0};for(var n in e)"string"==typeof e[n]&&o.total++;var s=function(){o.loaded++,o.loaded===o.total&&i&&i()};for(var r in e){var a=e[r],c=new t.Sampler(a,s);c.connect(this.output),this.samples[r]=c}},t.MultiSampler.prototype.triggerAttack=function(t,e){this.samples.hasOwnProperty(t)&&this.samples[t].triggerAttack(e)},t.MultiSampler.prototype.triggerRelease=function(t,e){this.samples.hasOwnProperty(t)&&this.samples[t].triggerRelease(e)},t.MultiSampler.prototype.set=function(t){for(var e in this.samples)this.samples[e].set(t)},t.MultiSampler.prototype.setVolume=t.Source.prototype.setVolume,t.MultiSampler.prototype.dispose=function(){t.prototype.dispose.call(this);for(var e in this.samples)this.samples[e].dispose(),this.samples[e]=null;this.samples=null},t.MultiSampler}),define("Tone/instrument/PolySynth",["Tone/core/Tone","Tone/instrument/MonoSynth","Tone/source/Source"],function(t){return t.PolySynth=function(){var e=this.optionsObject(arguments,["polyphony","voice","voiceOptions"],t.PolySynth.defaults);this.output=this.context.createGain(),this._voices=new Array(e.polyphony),this._freeVoices=[],this._activeVoices={};for(var i=0;i0){var n=this._freeVoices.shift();n.triggerAttack(t,e,i),this._activeVoices[o]=n}},t.PolySynth.prototype.triggerAttackRelease=function(t,e,i,o){i=this.toSeconds(i),this.triggerAttack(t,i,o),this.triggerRelease(t,i+this.toSeconds(e))},t.PolySynth.prototype.triggerRelease=function(t,e){var i=JSON.stringify(t),o=this._activeVoices[i];o&&(o.triggerRelease(e),this._freeVoices.push(o),this._activeVoices[i]=null)},t.PolySynth.prototype.set=function(t){for(var e=0;ei){var o=e;e=i,i=o}this._min=new t.Min(i),this._max=new t.Max(e),this.chain(this.input,this._min,this._max,this.output)},t.extend(t.Clip),t.Clip.prototype.setMin=function(t){this._min.setMin(t)},t.Clip.prototype.setMax=function(t){this._max.setMax(t)},t.Clip.prototype.connect=t.Signal.prototype.connect,t.Clip.prototype.dispose=function(){t.prototype.dispose.call(this),this._min.dispose(),this._max.dispose(),this._min=null,this._max=null},t.Clip}),define("Tone/signal/Route",["Tone/core/Tone","Tone/signal/Equal","Tone/signal/Signal"],function(t){t.Route=function(i){i=this.defaultArg(i,2),this.output=new Array(i),this.input=this.context.createGain(),this.gate=new t.Signal(0);for(var o=0;i>o;o++){var n=new e(o);this.output[o]=n,this.gate.connect(n.selecter),this.input.connect(n)}},t.extend(t.Route),t.Route.prototype.select=function(t,e){t=Math.floor(t),this.gate.setValueAtTime(t,this.toSeconds(e))},t.Route.prototype.connect=t.Signal.prototype.connect,t.Route.prototype.dispose=function(){this.gate.dispose();for(var e=0;ef;f++){var d=2*Math.random()-1;o=.99886*o+.0555179*d,r=.99332*r+.0750759*d,a=.969*a+.153852*d,c=.8665*c+.3104856*d,h=.55*h+.5329522*d,l=-.7616*l-.016898*d,p[f]=o+r+a+c+h+l+u+.5362*d,p[f]*=.11,u=.115926*d}}return e}(),i=function(){for(var e=t.createBuffer(2,s,n),i=0;ia;a++){var c=2*Math.random()-1;o[a]=(r+.02*c)/1.02,r=o[a],o[a]*=3.5}return e}(),o=function(){for(var e=t.createBuffer(2,s,n),i=0;ir;r++)o[r]=2*Math.random()-1;return e}()}),t.Noise}),define("Tone/source/PulseOscillator",["Tone/core/Tone","Tone/source/Source","Tone/source/Oscillator","Tone/signal/Signal","Tone/signal/Threshold"],function(t){for(var e=new Float32Array(256),i=0;128>i;i++)e[i]=-1,e[i+128]=1;return t.PulseOscillator=function(i,o){t.Source.call(this),this.width=new t.Signal(this.defaultArg(o,.5)),this._sawtooth=new t.Oscillator(i,"sawtooth"),this.frequency=this._sawtooth.frequency,this.detune=this._sawtooth.detune,this._thresh=this.context.createWaveShaper(),this._thresh.curve=e,this.chain(this._sawtooth,this._thresh,this.output),this.width.connect(this._thresh)},t.extend(t.PulseOscillator,t.Source),t.PulseOscillator.prototype.setWidth=function(t){this.width.setValue(t)},t.PulseOscillator.prototype.start=function(e){this.state===t.Source.State.STOPPED&&(e=this.toSeconds(e),this._sawtooth.start(e),this.width.output.gain.setValueAtTime(1,e),this.state=t.Source.State.STARTED)},t.PulseOscillator.prototype.stop=function(e){this.state===t.Source.State.STARTED&&(e=this.toSeconds(e),this._sawtooth.stop(e),this.width.output.gain.setValueAtTime(0,e),this.state=t.Source.State.STOPPED)},t.PulseOscillator.prototype.dispose=function(){t.Source.prototype.dispose.call(this),this._sawtooth.dispose(),this.width.dispose(),this._thresh.disconnect(),this._sawtooth=null,this.frequency=null,this.detune=null,this.width=null,this._thresh=null},t.PulseOscillator}) \ No newline at end of file +!function(t){"function"!=typeof define&&"function"!=typeof t.Tone&&(t.define=function(){var e=arguments[arguments.length-1],i=arguments[0];"Tone/core/Tone"===i?t.Tone=e():"function"==typeof e&&e(t.Tone)})}(this),define("Tone/core/Tone",[],function(){function t(t){return void 0===t}var e;if(t(window.AudioContext)&&(window.AudioContext=window.webkitAudioContext),t(window.OfflineAudioContext)&&(window.OfflineAudioContext=window.webkitOfflineAudioContext),t(AudioContext))throw new Error("Web Audio is not supported in this browser");e=new AudioContext,"function"!=typeof AudioContext.prototype.createGain&&(AudioContext.prototype.createGain=AudioContext.prototype.createGainNode),"function"!=typeof AudioContext.prototype.createDelay&&(AudioContext.prototype.createDelay=AudioContext.prototype.createDelayNode),"function"!=typeof AudioContext.prototype.createPeriodicWave&&(AudioContext.prototype.createPeriodicWave=AudioContext.prototype.createWaveTable),"function"!=typeof AudioBufferSourceNode.prototype.start&&(AudioBufferSourceNode.prototype.start=AudioBufferSourceNode.prototype.noteGrainOn),"function"!=typeof AudioBufferSourceNode.prototype.stop&&(AudioBufferSourceNode.prototype.stop=AudioBufferSourceNode.prototype.noteOff),"function"!=typeof OscillatorNode.prototype.start&&(OscillatorNode.prototype.start=OscillatorNode.prototype.noteOn),"function"!=typeof OscillatorNode.prototype.stop&&(OscillatorNode.prototype.stop=OscillatorNode.prototype.noteOff),"function"!=typeof OscillatorNode.prototype.setPeriodicWave&&(OscillatorNode.prototype.setPeriodicWave=OscillatorNode.prototype.setWaveTable),AudioNode.prototype._nativeConnect=AudioNode.prototype.connect,AudioNode.prototype.connect=function(e,i,n){if(e.input)Array.isArray(e.input)?(t(n)&&(n=0),this.connect(e.input[n])):this.connect(e.input);else try{e instanceof AudioNode?this._nativeConnect(e,i,n):this._nativeConnect(e,i)}catch(o){throw new Error("error connecting to node: "+e)}};var i=function(){this.input=this.context.createGain(),this.output=this.context.createGain()};i.context=e,i.prototype.context=i.context,i.prototype.bufferSize=2048,i.prototype.connect=function(t,e,i){Array.isArray(this.output)?(e=this.defaultArg(e,0),this.output[e].connect(t,0,i)):this.output.connect(t,e,i)},i.prototype.disconnect=function(){this.output.disconnect()},i.prototype.chain=function(){if(arguments.length>1)for(var t=arguments[0],e=1;e1)for(var e=1;ei){var n=i;i=e,e=n}else if(e==i)return 0;return(t-e)/(i-e)},i.prototype.dispose=function(){this.isUndef(this.input)||(this.input instanceof AudioNode&&this.input.disconnect(),this.input=null),this.isUndef(this.output)||(this.output instanceof AudioNode&&this.output.disconnect(),this.output=null)};var n=null;i.prototype.noGC=function(){this.output.connect(n)},AudioNode.prototype.noGC=function(){this.connect(n)},i.prototype.now=function(){return this.context.currentTime},i.prototype.samplesToSeconds=function(t){return t/this.context.sampleRate},i.prototype.toSamples=function(t){var e=this.toSeconds(t);return Math.round(e*this.context.sampleRate)},i.prototype.toSeconds=function(t,e){if(e=this.defaultArg(e,this.now()),"number"==typeof t)return t;if("string"==typeof t){var i=0;return"+"===t.charAt(0)&&(t=t.slice(1),i=e),parseFloat(t)+i}return e},i.prototype.frequencyToSeconds=function(t){return 1/parseFloat(t)},i.prototype.secondsToFrequency=function(t){return 1/t};var o=[];return i._initAudioContext=function(t){t(i.context),o.push(t)},i.setContext=function(t){i.prototype.context=t,i.context=t;for(var e=0;es;s++)o[s]=1;i.curve=o,e.connect(i),e.start(0),e.noGC()}),t.Signal}),define("Tone/component/Envelope",["Tone/core/Tone","Tone/signal/Signal"],function(t){return t.Envelope=function(){var e=this.optionsObject(arguments,["attack","decay","sustain","release"],t.Envelope.defaults);this.output=this.context.createGain(),this.attack=this.toSeconds(e.attack),this.decay=this.toSeconds(e.decay),this.sustain=this.toSeconds(e.sustain),this.release=this.toSeconds(e.release),this.min=this.toSeconds(e.min),this.max=this.toSeconds(e.max),this._control=new t.Signal(this.min),this._control.connect(this.output)},t.extend(t.Envelope),t.Envelope.defaults={attack:.01,decay:.1,sustain:.5,release:1,min:0,max:1},t.Envelope.prototype.set=function(t){this.isUndef(t.attack)||this.setAttack(t.attack),this.isUndef(t.decay)||this.setDecay(t.decay),this.isUndef(t.sustain)||this.setSustain(t.sustain),this.isUndef(t.release)||this.setRelease(t.release),this.isUndef(t.min)||this.setMin(t.min),this.isUndef(t.max)||this.setMax(t.max)},t.Envelope.prototype.setAttack=function(t){this.attack=this.toSeconds(t)},t.Envelope.prototype.setDecay=function(t){this.decay=this.toSeconds(t)},t.Envelope.prototype.setRelease=function(t){this.release=this.toSeconds(t)},t.Envelope.prototype.setSustain=function(t){this.sustain=t},t.Envelope.prototype.setMax=function(t){this.max=t},t.Envelope.prototype.setMin=function(t){this.min=t,this._control.setValueAtTime(this.min,this.now())},t.Envelope.prototype.triggerAttack=function(t,e){e=this.defaultArg(e,1);var i=this.max*e,n=(i-this.min)*this.sustain+this.min;t=this.toSeconds(t),this._control.cancelScheduledValues(t),this._control.setTargetAtTime(i,t,this.attack/4),this._control.setTargetAtTime(n,t+this.attack,this.decay/4)},t.Envelope.prototype.triggerRelease=function(t){t=this.toSeconds(t),this._control.cancelScheduledValues(t),this._control.setTargetAtTime(this.min,t,this.toSeconds(this.release)/4)},t.Envelope.prototype.triggerAttackRelease=function(t,e,i){e=this.toSeconds(e),this.triggerAttack(e,i),this.triggerRelease(e+this.toSeconds(t))},t.Envelope.prototype.connect=t.Signal.prototype.connect,t.Envelope.prototype.dispose=function(){t.prototype.dispose.call(this),this._control.dispose(),this._control=null},t.Envelope}),define("Tone/component/AmplitudeEnvelope",["Tone/core/Tone","Tone/component/Envelope"],function(t){return t.AmplitudeEnvelope=function(){t.Envelope.apply(this,arguments),this.input=this.context.createGain(),this._control.disconnect(),this._control.connect(this.output.gain),this.input.connect(this.output)},t.extend(t.AmplitudeEnvelope,t.Envelope),t.AmplitudeEnvelope.prototype.dispose=function(){t.Envelope.prototype.dispose.call(this)},t.AmplitudeEnvelope}),define("Tone/signal/Add",["Tone/core/Tone","Tone/signal/Signal"],function(t){return t.Add=function(e){this._value=new t.Signal(e),this.input=this.output=this.context.createGain(),this._value.connect(this.output)},t.extend(t.Add),t.Add.prototype.setValue=function(t){this._value.setValue(t)},t.Add.prototype.connect=t.Signal.prototype.connect,t.Add.prototype.dispose=function(){t.prototype.dispose.call(this),this._value.dispose(),this._value=null},t.Add}),define("Tone/signal/Multiply",["Tone/core/Tone","Tone/signal/Signal"],function(t){return t.Multiply=function(t){this.input=this.output=this.context.createGain(),this.input.gain.value=this.defaultArg(t,1)},t.extend(t.Multiply),t.Multiply.prototype.setValue=function(t){this.input.gain.value=t},t.Multiply.prototype.connect=t.Signal.prototype.connect,t.Multiply.prototype.dispose=function(){t.prototype.dispose.call(this)},t.Multiply}),define("Tone/signal/Scale",["Tone/core/Tone","Tone/signal/Add","Tone/signal/Multiply","Tone/signal/Signal"],function(t){return t.Scale=function(e,i,n,o){t.call(this),2==arguments.length&&(n=e,o=i,e=-1,i=1),this._inputMin=e,this._inputMax=i,this._outputMin=n,this._outputMax=o,this._plusInput=new t.Add(0),this._scale=new t.Multiply(1),this._plusOutput=new t.Add(0),this.chain(this.input,this._plusInput,this._scale,this._plusOutput,this.output),this._setScalingParameters()},t.extend(t.Scale),t.Scale.prototype._setScalingParameters=function(){this._plusInput.setValue(-this._inputMin),this._scale.setValue((this._outputMax-this._outputMin)/(this._inputMax-this._inputMin)),this._plusOutput.setValue(this._outputMin)},t.Scale.prototype.setInputMin=function(t){this._inputMin=t,this._setScalingParameters()},t.Scale.prototype.setInputMax=function(t){this._inputMax=t,this._setScalingParameters()},t.Scale.prototype.setOutputMin=function(t){this._outputMin=t,this._setScalingParameters()},t.Scale.prototype.setOutputMax=function(t){this._outputMax=t,this._setScalingParameters()},t.Scale.prototype.connect=t.Signal.prototype.connect,t.Scale.prototype.dispose=function(){t.prototype.dispose.call(this),this._plusInput.dispose(),this._plusOutput.dispose(),this._scale.dispose(),this._plusInput=null,this._plusOutput=null,this._scale=null},t.Scale}),define("Tone/component/DryWet",["Tone/core/Tone","Tone/signal/Signal","Tone/signal/Scale"],function(t){return t.DryWet=function(e){t.call(this),this.dry=this.input,this.wet=this.context.createGain(),this.wetness=new t.Signal,this._invert=new t.Scale(0,1,1,0),this.dry.connect(this.output),this.wet.connect(this.output),this.chain(this.wetness,this.wet.gain),this.chain(this.wetness,this._invert,this.dry.gain),this.setDry(this.defaultArg(e,0))},t.extend(t.DryWet),t.DryWet.prototype.setDry=function(t,e){this.setWet(1-t,e)},t.DryWet.prototype.setWet=function(t,e){e?this.wetness.linearRampToValueNow(t,e):this.wetness.setValue(t)},t.DryWet.prototype.dispose=function(){t.prototype.dispose.call(this),this.dry.disconnect(),this.wet.disconnect(),this.wetness.dispose(),this._invert.dispose(),this.dry=null,this.wet=null,this.wetness=null,this._invert=null},t.DryWet}),define("Tone/component/Filter",["Tone/core/Tone","Tone/signal/Signal"],function(t){return t.Filter=function(){t.call(this);var e=this.optionsObject(arguments,["frequency","type","rolloff"],t.Filter.defaults);this._filters=[],this.frequency=new t.Signal(e.frequency),this.detune=new t.Signal(0),this.gain=new t.Signal(e.gain),this.Q=new t.Signal(e.Q),this._type=e.type,this.setRolloff(e.rolloff)},t.extend(t.Filter),t.Filter.defaults={type:"lowpass",frequency:350,rolloff:-12,Q:1,gain:0},t.Filter.prototype.set=function(t){this.isUndef(t.type)||this.setType(t.type),this.isUndef(t.detune)||this.detune.setValue(t.detune),this.isUndef(t.frequency)||this.frequency.setValue(t.frequency),this.isUndef(t.Q)||this.Q.setValue(t.Q),this.isUndef(t.gain)||this.gain.setValue(t.gain),this.isUndef(t.rolloff)||this.setRolloff(t.rolloff)},t.Filter.prototype.setType=function(t){this._type=t;for(var e=0;en;n++){var o=this.context.createBiquadFilter();o.type=this._type,this.frequency.connect(o.frequency),this.detune.connect(o.detune),this.Q.connect(o.Q),this.gain.connect(o.gain),this._filters[n]=o}var s=[this.input].concat(this._filters).concat([this.output]);this.chain.apply(this,s)},t.Filter.prototype.dispose=function(){t.prototype.dispose.call(this);for(var e=0;en;n++){var o=n/e*2-1;i[n]=o>=0?Math.pow(o,t):o}this._expScaler.curve=i},t.ScaleExp.prototype.setInputMin=function(t){this._inputMin=t,this._setScalingParameters()},t.ScaleExp.prototype.setInputMax=function(t){this._inputMax=t,this._setScalingParameters()},t.ScaleExp.prototype.setOutputMin=function(t){this._outputMin=t,this._setScalingParameters()},t.ScaleExp.prototype.setOutputMax=function(t){this._outputMax=t,this._setScalingParameters()},t.ScaleExp.prototype.connect=t.Signal.prototype.connect,t.ScaleExp.prototype.dispose=function(){t.prototype.dispose.call(this),this._plusInput.dispose(),this._plusOutput.dispose(),this._normalize.dispose(),this._scale.dispose(),this._expScaler.disconnect(),this._plusInput=null,this._plusOutput=null,this._scale=null,this._normalize=null,this._expScaler=null},t.ScaleExp}),define("Tone/component/FeedbackCombFilter",["Tone/core/Tone","Tone/signal/ScaleExp","Tone/signal/Signal"],function(t){return t.FeedbackCombFilter=function(e){t.call(this),e=this.defaultArg(e,.01);var i=Math.ceil(this.bufferSize/(e*this.context.sampleRate));i=Math.min(i,10),i=Math.max(i,1),this._delayCount=i,this._delays=new Array(this._delayCount),this._delayTime=new t.Signal(1),this.resonance=new t.Signal(.5),this._resScale=new t.ScaleExp(0,1,.01,1/this._delayCount-.001,.5),this._highFrequencies=!1,this._feedback=this.context.createGain();for(var n=0;nn){this._highFrequencies=!0;for(var s=Math.round(n/o*this._delayCount),r=0;s>r;r++)this._delays[r].delayTime.setValueAtTime(1/i,e);t=Math.floor(n)/i}else if(this._highFrequencies){this._highFrequencies=!1;for(var a=0;ao;o++){var s,r=o/(i-1)*2-1;s=e>r?0:1,n[o]=s}t.curve=n},t.Threshold.prototype.setThreshold=function(t){this._setThresh(this._thresh,t)},t.Threshold.prototype.connect=t.Signal.prototype.connect,t.Threshold.prototype.dispose=function(){t.prototype.dispose.call(this),this._thresh.disconnect(),this._doubleThresh.disconnect(),this._thresh=null,this._doubleThresh=null},t.Threshold}),define("Tone/signal/EqualZero",["Tone/core/Tone","Tone/signal/Threshold","Tone/signal/Signal"],function(t){return t.EqualZero=function(){this._equals=this.context.createWaveShaper(),this._thresh=new t.Threshold(1),this.input=this._equals,this._equals.connect(this._thresh),this.output=this._thresh,this._setEquals()},t.extend(t.EqualZero),t.EqualZero.prototype._setEquals=function(){for(var t=1023,e=new Float32Array(t),i=0;t>i;i++){var n=i/(t-1)*2-1;e[i]=0===n?1:0}this._equals.curve=e},t.EqualZero.prototype.connect=t.Signal.prototype.connect,t.EqualZero.prototype.dispose=function(){t.prototype.dispose.call(this),this._equals.disconnect(),this._thresh.dispose(),this._equals=null,this._thresh=null},t.EqualZero}),define("Tone/signal/Equal",["Tone/core/Tone","Tone/signal/EqualZero","Tone/signal/Add","Tone/signal/Signal"],function(t){return t.Equal=function(e){this._adder=new t.Add(-e),this._equals=new t.EqualZero,this.input=this._adder,this.output=this._equals,this._adder.connect(this._equals)},t.extend(t.Equal),t.Equal.prototype.setValue=function(t){this._adder.setValue(-t)},t.Equal.prototype.connect=t.Signal.prototype.connect,t.Equal.prototype.dispose=function(){t.prototype.dispose.call(this),this._equals.disconnect(),this._adder.dispose(),this._equals=null,this._adder=null},t.Equal}),define("Tone/signal/Select",["Tone/core/Tone","Tone/signal/Equal","Tone/signal/Signal"],function(t){t.Select=function(i){i=this.defaultArg(i,2),this.input=new Array(i),this.output=this.context.createGain(),this.gate=new t.Signal(0);for(var n=0;i>n;n++){var o=new e(n);this.input[n]=o,this.gate.connect(o.selecter),o.connect(this.output)}},t.extend(t.Select),t.Select.prototype.select=function(t,e){t=Math.floor(t),this.gate.setValueAtTime(t,this.toSeconds(e))},t.Select.prototype.connect=t.Signal.prototype.connect,t.Select.prototype.dispose=function(){this.gate.dispose();for(var e=0;eo;o++){var s,r=o/(i-1)*2-1;s=0>=r?t:e,n[o]=s}this._frequencyValues.curve=n},t.Follower.prototype.setAttack=function(t){this._attack=this.secondsToFrequency(t),this._setAttackRelease(this._attack,this._release)},t.Follower.prototype.setRelease=function(t){this._release=this.secondsToFrequency(t),this._setAttackRelease(this._attack,this._release)},t.Follower.prototype.set=function(e){this.isUndef(e.attack)||this.setAttack(e.attack),this.isUndef(e.release)||this.setRelease(e.release),t.Effect.prototype.set.call(this,e)},t.Follower.prototype.connect=t.Signal.prototype.connect,t.Follower.prototype.dispose=function(){t.prototype.dispose.call(this),this._filter.disconnect(),this._frequencyValues.disconnect(),this._delay.disconnect(),this._difference.disconnect(),this._abs.dispose(),this._negate.dispose(),this._mult.dispose(),this._filter=null,this._delay=null,this._frequencyValues=null,this._abs=null,this._negate=null,this._difference=null,this._mult=null},t.Follower}),define("Tone/signal/GreaterThan",["Tone/core/Tone","Tone/signal/LessThan","Tone/signal/Negate","Tone/signal/Signal"],function(t){return t.GreaterThan=function(e){this._lt=new t.LessThan(-e),this._neg=new t.Negate,this.input=this._neg,this.output=this._lt,this._neg.connect(this._lt)},t.extend(t.GreaterThan),t.GreaterThan.prototype.setValue=function(t){this._lt.setValue(-t)},t.GreaterThan.prototype.connect=t.Signal.prototype.connect,t.GreaterThan.prototype.dispose=function(){t.prototype.dispose.call(this),this._lt.disconnect(),this._neg.disconnect(),this._lt=null,this._neg=null},t.GreaterThan}),define("Tone/component/Gate",["Tone/core/Tone","Tone/component/Follower","Tone/signal/GreaterThan"],function(t){return t.Gate=function(e,i,n){t.call(this),e=this.defaultArg(e,-40),i=this.defaultArg(i,.1),n=this.defaultArg(n,.2),this._follower=new t.Follower(i,n),this._gt=new t.GreaterThan(this.dbToGain(e)),this.chain(this.input,this.output),this.chain(this.input,this._gt,this._follower,this.output.gain)},t.extend(t.Gate),t.Gate.prototype.setThreshold=function(t){this._gt.setValue(this.dbToGain(t))},t.Gate.prototype.setAttack=function(t){this._follower.setAttack(t)},t.Gate.prototype.setRelease=function(t){this._follower.setRelease(t)},t.Gate.prototype.dispose=function(){t.prototype.dispose.call(this),this._follower.dispose(),this._gt.dispose(),this._follower=null,this._gt=null},t.Gate}),define("Tone/core/Clock",["Tone/core/Tone","Tone/signal/Signal"],function(t){return t.Clock=function(e,i){this._oscillator=null,this._jsNode=this.context.createScriptProcessor(this.bufferSize,1,1),this._jsNode.onaudioprocess=this._processBuffer.bind(this),this._controlSignal=new t.Signal(1),this._upTick=!1,this.tick=this.defaultArg(i,function(){}),this._jsNode.noGC(),this.setRate(e)},t.extend(t.Clock),t.Clock.prototype.setRate=function(t,e){var i=this.secondsToFrequency(this.toSeconds(t));e?this._controlSignal.exponentialRampToValueNow(i,e):(this._controlSignal.cancelScheduledValues(0),this._controlSignal.setValue(i))},t.Clock.prototype.getRate=function(){return this._controlSignal.getValue()},t.Clock.prototype.start=function(t){this._oscillator=this.context.createOscillator(),this._oscillator.type="square",this._oscillator.connect(this._jsNode),this._controlSignal.connect(this._oscillator.frequency),this._upTick=!1;var e=this.toSeconds(t);this._oscillator.start(e),this._oscillator.onended=function(){}},t.Clock.prototype.stop=function(t,e){var i=this.toSeconds(t);this._oscillator.onended=e,this._oscillator.stop(i)},t.Clock.prototype._processBuffer=function(t){for(var e=this.defaultArg(t.playbackTime,this.now()),i=this._jsNode.bufferSize,n=t.inputBuffer.getChannelData(0),o=this._upTick,s=this,r=0;i>r;r++){var a=n[r];a>0&&!o?(o=!0,setTimeout(function(){var t=e+s.samplesToSeconds(r+2*i);return function(){s.tick(t)}}(),0)):0>a&&o&&(o=!1)}this._upTick=o +},t.Clock.prototype.dispose=function(){this._jsNode.disconnect(),this._controlSignal.dispose(),this._oscillator&&(this._oscillator.onended(),this._oscillator.disconnect()),this._jsNode.onaudioprocess=function(){},this._jsNode=null,this._controlSignal=null,this._oscillator=null},t.Clock}),define("Tone/core/Transport",["Tone/core/Tone","Tone/core/Clock","Tone/signal/Signal"],function(Tone){Tone.Transport=function(){this._clock=new Tone.Clock(1,this._processTick.bind(this)),this.loop=!1,this.state=TransportState.STOPPED},Tone.extend(Tone.Transport);var timelineTicks=0,transportTicks=0,tatum=12,transportTimeSignature=4,loopStart=0,loopEnd=4*tatum,intervals=[],timeouts=[],transportTimeline=[],timelineProgress=0,SyncedSources=[],TransportState={STARTED:"started",PAUSED:"paused",STOPPED:"stopped"};Tone.Transport.prototype._processTick=function(t){this.state===TransportState.STARTED&&(processIntervals(t),processTimeouts(t),processTimeline(t),transportTicks+=1,timelineTicks+=1,this.loop&&timelineTicks===loopEnd&&this._setTicks(loopStart))},Tone.Transport.prototype._setTicks=function(t){timelineTicks=t;for(var e=0;e=t){timelineProgress=e;break}}};var processIntervals=function(t){for(var e=0,i=intervals.length;i>e;e++){var n=intervals[e];n.testInterval(transportTicks)&&n.doCallback(t)}},processTimeouts=function(t){for(var e=0,i=0,n=timeouts.length;n>i;i++){var o=timeouts[i],s=o.callbackTick();if(transportTicks>=s)o.doCallback(t),e++;else if(s>transportTicks)break}timeouts.splice(0,e)},processTimeline=function(t){for(var e=timelineProgress,i=transportTimeline.length;i>e;e++){var n=transportTimeline[e],o=n.callbackTick();if(o===timelineTicks)timelineProgress=e,n.doCallback(t);else if(o>timelineTicks)break}};Tone.Transport.prototype.setInterval=function(t,e,i){var n=this.toTicks(e),o=new TimelineEvent(t,i,n,transportTicks);return intervals.push(o),o.id},Tone.Transport.prototype.clearInterval=function(t){for(var e=0;es;s++){var a=timeouts[s];if(a.callbackTick()>o.callbackTick())return timeouts.splice(s,0,o),o.id}return timeouts.push(o),o.id},Tone.Transport.prototype.clearTimeout=function(t){for(var e=0;es;s++){var a=transportTimeline[s];if(a.callbackTick()>o.callbackTick())return transportTimeline.splice(s,0,o),o.id}return transportTimeline.push(o),o.id},Tone.Transport.prototype.clearTimeline=function(t){for(var e=0;e1){for(var oringalTime=time,i=0;ir;++r){var a,c=2/(r*Math.PI);switch(t){case"sine":a=1===r?1:0;break;case"square":a=1&r?2*c:0;break;case"sawtooth":a=c*(1&r?1:-1);break;case"triangle":a=1&r?2*c*c*(r-1>>1&1?-1:1):0;break;default:throw new TypeError("invalid oscillator type: "+t)}0!==a?(n[r]=-a*Math.sin(s),o[r]=a*Math.cos(s)):(n[r]=0,o[r]=0)}var l=this.context.createPeriodicWave(n,o);this._wave=l,this.oscillator.setPeriodicWave(this._wave),this._type=t},t.Oscillator.prototype.getType=function(){return this._type},t.Oscillator.prototype.setPhase=function(t){this._phase=t*Math.PI/180,this.setType(this._type)},t.Oscillator.prototype.set=function(t){this.isUndef(t.type)||this.setType(t.type),this.isUndef(t.phase)||this.setPhase(t.phase),this.isUndef(t.frequency)||this.frequency.setValue(t.frequency),this.isUndef(t.onended)||(this.onended=t.onended),this.isUndef(t.detune)||this.detune.setValue(t.detune)},t.Oscillator.prototype._onended=function(){this.state=t.Source.State.STOPPED,this.onended()},t.Oscillator.prototype.dispose=function(){t.Source.prototype.dispose.call(this),this.stop(),null!==this.oscillator&&(this.oscillator.disconnect(),this.oscillator=null),this.frequency.dispose(),this.detune.dispose(),this._wave=null,this.detune=null,this.frequency=null},t.Oscillator}),define("Tone/component/LFO",["Tone/core/Tone","Tone/source/Oscillator","Tone/signal/Scale","Tone/signal/Signal"],function(t){return t.LFO=function(e,i,n){this.oscillator=new t.Oscillator(this.defaultArg(e,1),"sine"),this.frequency=this.oscillator.frequency,this._scaler=new t.Scale(this.defaultArg(i,0),this.defaultArg(n,1)),this.output=this._scaler,this.chain(this.oscillator,this.output)},t.extend(t.LFO),t.LFO.prototype.start=function(t){this.oscillator.start(t)},t.LFO.prototype.stop=function(t){this.oscillator.stop(t)},t.LFO.prototype.sync=function(e){t.Transport.syncSource(this.oscillator,e),t.Transport.syncSignal(this.oscillator.frequency)},t.LFO.prototype.unsync=function(){t.Transport.unsyncSource(this.oscillator),t.Transport.unsyncSignal(this.oscillator.frequency)},t.LFO.prototype.setFrequency=function(t){this.oscillator.setFrequency(t)},t.LFO.prototype.setPhase=function(t){this.oscillator.setPhase(t)},t.LFO.prototype.setMin=function(t){this._scaler.setOutputMin(t)},t.LFO.prototype.setMax=function(t){this._scaler.setOutputMax(t)},t.LFO.prototype.setType=function(t){this.oscillator.setType(t)},t.LFO.prototype.set=function(t){this.isUndef(t.frequency)||this.setFrequency(t.frequency),this.isUndef(t.type)||this.setType(t.type),this.isUndef(t.min)||this.setMin(t.min),this.isUndef(t.max)||this.setMax(t.max)},t.LFO.prototype.connect=t.Signal.prototype.connect,t.LFO.prototype.dispose=function(){t.prototype.dispose.call(this),this.oscillator.dispose(),this._scaler.dispose(),this._scaler=null,this.oscillator=null,this.frequency=null},t.LFO}),define("Tone/component/LowpassCombFilter",["Tone/core/Tone","Tone/signal/ScaleExp","Tone/signal/Signal"],function(t){t.LowpassCombFilter=function(i){t.call(this),i=this.defaultArg(i,.01);var n=Math.ceil(this.bufferSize/(i*this.context.sampleRate));n=Math.min(n,10),n=Math.max(n,1),this._filterDelayCount=n,this._filterDelays=new Array(this._filterDelayCount),this._delayTime=new t.Signal(1),this.dampening=new t.Signal(3e3),this.resonance=new t.Signal(.5),this._resScale=new t.ScaleExp(0,1,.01,1/this._filterDelayCount-.001,.5),this._highFrequencies=!1,this._feedback=this.context.createGain();for(var o=0;on){this._highFrequencies=!0;for(var s=Math.round(n/o*this._filterDelayCount),r=0;s>r;r++)this._filterDelays[r].setDelay(1/i,e);t=Math.floor(n)/i}else if(this._highFrequencies){this._highFrequencies=!1;for(var a=0;al;l++)o=s[l],!c&&o>.95&&(c=!0,this._lastClip=Date.now()),a+=o,r+=o*o;var h=a/e,u=Math.sqrt(r/e);this._volume[n]=Math.max(u,this._volume[n]*i),this._values[n]=h}},t.Meter.prototype.getLevel=function(t){t=this.defaultArg(t,0);var e=this._volume[t];return 1e-5>e?0:e},t.Meter.prototype.getValue=function(t){return t=this.defaultArg(t,0),this._values[t]},t.Meter.prototype.getDb=function(t){return this.gainToDb(this.getLevel(t))},t.Meter.prototype.isClipped=function(){return Date.now()-this._lastClipthis._recordEndSample?(this.state=e.STOPPED,this._callback(this._recordBuffers)):s>this._recordStartSample?(i=0,n=Math.min(this._recordEndSample-s,r),this._recordChannels(t.inputBuffer,i,n,r)):a>this._recordStartSample&&(n=a-this._recordStartSample,i=r-n,this._recordChannels(t.inputBuffer,i,n,r))}},t.Recorder.prototype._recordChannels=function(t,e,i,n){for(var o=this._recordBufferOffset,s=this._recordBuffers,r=0;rc;c++){var l=c-e;s[r][l+o]=a[c]}}this._recordBufferOffset+=i},t.Recorder.prototype.record=function(t,i,n){if(this.state===e.STOPPED){this.clear(),this._recordBufferOffset=0,i=this.defaultArg(i,0),this._recordDuration=this.toSamples(t),this._recordStartSample=this.toSamples("+"+i),this._recordEndSample=this._recordStartSample+this._recordDuration;for(var o=0;os;s++){var a=o[s];Array.isArray(n)?a.apply(window,[e].concat(n)):a(e,n)}}t.Note=function(e,i,n){this.value=n,this._channel=e,this._timelineID=t.Transport.setTimeline(this._trigger.bind(this),i)},t.Note.prototype._trigger=function(t){e(this._channel,t,this.value)},t.Note.prototype.dispose=function(){t.Tranport.clearTimeline(this._timelineID),this.value=null};var i={};t.Note.route=function(t,e){i.hasOwnProperty(t)?i[t].push(e):i[t]=[e]},t.Note.unroute=function(t,e){if(i.hasOwnProperty(t)){var n=i[t],o=n.indexOf(e);-1!==o&&i[t].splice(o,1)}},t.Note.parseScore=function(e){var i=[];for(var n in e){var o=e[n];if("tempo"===n)t.Transport.setBpm(o);else if("timeSignature"===n)t.Transport.setTimeSignature(o[0],o[1]);else{if(!Array.isArray(o))throw new TypeError("score parts must be Arrays");for(var s=0;s=0;o--){var s=new e(i,Math.pow(2,o));this._modChain.push(s)}this.chain.apply(this,this._modChain),this.input.connect(this._modChain[0]),this._modChain[this._modChain.length-1].connect(this.output)},t.extend(t.Modulo),t.Modulo.prototype.dispose=function(){t.prototype.dispose.call(this);for(var e=0;eo;o++){var s=this.context.createBiquadFilter();s.type="allpass",s.Q.value=i,e.connect(s.frequency),n[o]=s}return this.chain.apply(this,n),n},t.Phaser.prototype.setDepth=function(t){this._depth=t;var e=this._baseFrequency+this._baseFrequency*t;this._lfoL.setMax(e),this._lfoR.setMax(e)},t.Phaser.prototype.setBaseFrequency=function(t){this._baseFrequency=t,this._lfoL.setMin(t),this._lfoR.setMin(t),this.setDepth(this._depth)},t.Phaser.prototype.setRate=function(t){this._lfoL.setFrequency(t)},t.Phaser.prototype.set=function(e){this.isUndef(e.rate)||this.setRate(e.rate),this.isUndef(e.baseFrequency)||this.setBaseFrequency(e.baseFrequency),this.isUndef(e.depth)||this.setDepth(e.depth),t.StereoFeedbackEffect.prototype.set.call(this,e)},t.Phaser.prototype.dispose=function(){t.StereoFeedbackEffect.prototype.dispose.call(this),this._lfoL.dispose(),this._lfoR.dispose();for(var e=0;e0){var i=this.frequency.getValue();this.frequency.setValueAtTime(i,e),this.frequency.exponentialRampToValueAtTime(t,e+this.portamento)}else this.frequency.setValueAtTime(t,e)},t.Monophonic.prototype.setPortamento=function(t){this.portamento=this.toSeconds(t)},t.Monophonic.prototype.set=function(t){this.isUndef(t.volume)||this.setVolume(t.volume),this.isUndef(t.portamento)||this.setPortamento(t.portamento)},t.Monophonic.prototype.setPreset=function(t){!this.isUndef(this.preset)&&this.preset.hasOwnProperty(t)&&this.set(this.preset[t])},t.Monophonic.prototype.dispose=function(){t.Instrument.prototype.dispose.call(this)},t.Monophonic}),define("Tone/instrument/MonoSynth",["Tone/core/Tone","Tone/component/Envelope","Tone/source/Oscillator","Tone/signal/Signal","Tone/component/Filter","Tone/signal/Add","Tone/instrument/Monophonic"],function(t){return t.MonoSynth=function(e){e=this.defaultArg(e,t.MonoSynth.defaults),t.Monophonic.call(this,e),this.oscillator=new t.Oscillator(0,e.oscType),this.frequency=this.oscillator.frequency,this.detune=this.oscillator.detune,this.filter=new t.Filter(e.filter),this.filterEnvelope=new t.Envelope(e.filterEnvelope),this.envelope=new t.Envelope(e.envelope),this._amplitude=this.context.createGain(),this.oscillator.connect(this.filter),this.filter.connect(this._amplitude),this.oscillator.start(),this.filterEnvelope.connect(this.filter.frequency),this.envelope.connect(this._amplitude.gain),this._amplitude.connect(this.output)},t.extend(t.MonoSynth,t.Monophonic),t.MonoSynth.defaults={oscType:"square",filter:{Q:6,type:"lowpass",rolloff:-24},envelope:{attack:.005,decay:.1,sustain:.9,release:1},filterEnvelope:{attack:.06,decay:.2,sustain:.5,release:2,min:20,max:4e3}},t.MonoSynth.prototype.triggerEnvelopeAttack=function(t,e){this.envelope.triggerAttack(t,e),this.filterEnvelope.triggerAttack(t)},t.MonoSynth.prototype.triggerEnvelopeRelease=function(t){this.envelope.triggerRelease(t),this.filterEnvelope.triggerRelease(t)},t.MonoSynth.prototype.setOscType=function(t){this.oscillator.setType(t)},t.MonoSynth.prototype.set=function(e){this.isUndef(e.detune)||this.detune.setValue(e.detune),this.isUndef(e.oscType)||this.setOscType(e.oscType),this.isUndef(e.filterEnvelope)||this.filterEnvelope.set(e.filterEnvelope),this.isUndef(e.envelope)||this.envelope.set(e.envelope),this.isUndef(e.filter)||this.filter.set(e.filter),t.Monophonic.prototype.set.call(this,e)},t.MonoSynth.prototype.dispose=function(){t.Monophonic.prototype.dispose.call(this),this.oscillator.dispose(),this.envelope.dispose(),this.filterEnvelope.dispose(),this.filter.dispose(),this._amplitude.disconnect(),this.oscillator=null,this.filterEnvelope=null,this.envelope=null,this.filter=null,this.detune=null,this._amplitude=null,this.frequency=null,this.detune=null},t.MonoSynth}),define("Tone/instrument/DuoSynth",["Tone/core/Tone","Tone/instrument/MonoSynth","Tone/component/LFO","Tone/signal/Signal","Tone/signal/Multiply","Tone/instrument/Monophonic"],function(t){return t.DuoSynth=function(e){e=this.defaultArg(e,t.DuoSynth.defaults),t.Monophonic.call(this,e),this.voice0=new t.MonoSynth(e.voice0),this.voice0.setVolume(-10),this.voice1=new t.MonoSynth(e.voice1),this.voice1.setVolume(-10),this._vibrato=new t.LFO(e.vibratoRate,-50,50),this._vibrato.start(),this._vibratoGain=this.context.createGain(),this._vibratoGain.gain.value=e.vibratoAmount,this._vibratoDelay=this.toSeconds(e.vibratoDelay),this._vibratoAmount=e.vibratoAmount,this.frequency=new t.Signal(440),this._harmonicity=new t.Multiply(e.harmonicity),this.frequency.connect(this.voice0.frequency),this.chain(this.frequency,this._harmonicity,this.voice1.frequency),this._vibrato.connect(this._vibratoGain),this.fan(this._vibratoGain,this.voice0.detune,this.voice1.detune),this.voice0.connect(this.output),this.voice1.connect(this.output)},t.extend(t.DuoSynth,t.Monophonic),t.DuoSynth.defaults={vibratoAmount:.5,vibratoRate:5,vibratoDelay:1,harmonicity:1.5,voice0:{volume:-10,portamento:0,oscType:"sine",filterEnvelope:{attack:.01,decay:0,sustain:1,release:.5},envelope:{attack:.01,decay:0,sustain:1,release:.5}},voice1:{volume:-10,portamento:0,oscType:"sine",filterEnvelope:{attack:.01,decay:0,sustain:1,release:.5},envelope:{attack:.01,decay:0,sustain:1,release:.5}}},t.DuoSynth.prototype.triggerEnvelopeAttack=function(t,e){t=this.toSeconds(t),this.voice0.envelope.triggerAttack(t,e),this.voice1.envelope.triggerAttack(t,e),this.voice0.filterEnvelope.triggerAttack(t),this.voice1.filterEnvelope.triggerAttack(t)},t.DuoSynth.prototype.triggerEnvelopeRelease=function(t){this.voice0.triggerRelease(t),this.voice1.triggerRelease(t)},t.DuoSynth.prototype.setHarmonicity=function(t){this._harmonicity.setValue(t)},t.DuoSynth.prototype.setPortamento=function(t){this.portamento=this.toSeconds(t)},t.DuoSynth.prototype.setVibratoDelay=function(t){this._vibratoDelay=this.toSeconds(t)},t.DuoSynth.prototype.setVibratoAmount=function(t){this._vibratoAmount=t,this._vibratoGain.gain.setValueAtTime(t,this.now())},t.DuoSynth.prototype.setVibratoRate=function(t){this._vibrato.setFrequency(t)},t.DuoSynth.prototype.setVolume=t.Source.prototype.setVolume,t.DuoSynth.prototype.set=function(e){this.isUndef(e.harmonicity)||this.setHarmonicity(e.harmonicity),this.isUndef(e.vibratoRate)||this.setVibratoRate(e.vibratoRate),this.isUndef(e.vibratoAmount)||this.setVibratoAmount(e.vibratoAmount),this.isUndef(e.vibratoDelay)||this.setVibratoDelay(e.vibratoDelay),this.isUndef(e.voice0)||this.voice0.set(e.voice0),this.isUndef(e.voice1)||this.voice1.set(e.voice1),t.Monophonic.prototype.set.call(this,e)},t.DuoSynth.prototype.dispose=function(){t.Monophonic.prototype.dispose.call(this),this.voice0.dispose(),this.voice1.dispose(),this.frequency.dispose(),this._vibrato.dispose(),this._vibratoGain.disconnect(),this._harmonicity.dispose(),this.voice0=null,this.voice1=null,this.frequency=null,this._vibrato=null,this._vibratoGain=null,this._harmonicity=null},t.DuoSynth}),define("Tone/instrument/FMSynth",["Tone/core/Tone","Tone/instrument/MonoSynth","Tone/signal/Signal","Tone/signal/Multiply","Tone/instrument/Monophonic"],function(t){return t.FMSynth=function(e){e=this.defaultArg(e,t.FMSynth.defaults),t.Monophonic.call(this,e),this.carrier=new t.MonoSynth(e.carrier),this.carrier.setVolume(-10),this.modulator=new t.MonoSynth(e.modulator),this.modulator.setVolume(-10),this.frequency=new t.Signal(440),this._harmonicity=new t.Multiply(e.harmonicity),this._modulationIndex=new t.Multiply(e.modulationIndex),this._modulationNode=this.context.createGain(),this.frequency.connect(this.carrier.frequency),this.chain(this.frequency,this._harmonicity,this.modulator.frequency),this.chain(this.frequency,this._modulationIndex,this._modulationNode),this.modulator.connect(this._modulationNode.gain),this._modulationNode.gain.value=0,this._modulationNode.connect(this.carrier.frequency),this.carrier.connect(this.output)},t.extend(t.FMSynth,t.Monophonic),t.FMSynth.defaults={harmonicity:3,modulationIndex:10,carrier:{volume:-10,portamento:0,oscType:"sine",envelope:{attack:.01,decay:0,sustain:1,release:.5},filterEnvelope:{attack:.01,decay:0,sustain:1,release:.5,min:2e4,max:2e4}},modulator:{volume:-10,portamento:0,oscType:"triangle",envelope:{attack:.01,decay:0,sustain:1,release:.5},filterEnvelope:{attack:.01,decay:0,sustain:1,release:.5,min:2e4,max:2e4}}},t.FMSynth.prototype.triggerEnvelopeAttack=function(t,e){t=this.toSeconds(t),this.carrier.envelope.triggerAttack(t,e),this.modulator.envelope.triggerAttack(t),this.carrier.filterEnvelope.triggerAttack(t),this.modulator.filterEnvelope.triggerAttack(t)},t.FMSynth.prototype.triggerEnvelopeRelease=function(t){this.carrier.triggerRelease(t),this.modulator.triggerRelease(t)},t.FMSynth.prototype.setHarmonicity=function(t){this._harmonicity.setValue(t)},t.FMSynth.prototype.setModulationIndex=function(t){this._modulationIndex.setValue(t)},t.FMSynth.prototype.set=function(e){this.isUndef(e.harmonicity)||this.setHarmonicity(e.harmonicity),this.isUndef(e.modulationIndex)||this.setModulationIndex(e.modulationIndex),this.isUndef(e.carrier)||this.carrier.set(e.carrier),this.isUndef(e.modulator)||this.modulator.set(e.modulator),t.Monophonic.prototype.set.call(this,e)},t.FMSynth.prototype.dispose=function(){t.Monophonic.prototype.dispose.call(this),this.carrier.dispose(),this.modulator.dispose(),this.frequency.dispose(),this._modulationIndex.dispose(),this._harmonicity.dispose(),this._modulationNode.disconnect(),this.carrier=null,this.modulator=null,this.frequency=null,this._modulationIndex=null,this._harmonicity=null,this._modulationNode=null},t.FMSynth}),define("Tone/source/Player",["Tone/core/Tone","Tone/source/Source"],function(t){return t.Player=function(e,i){t.Source.call(this),this._source=null,this._buffer=null,this.duration=0,this.loop=!1,this.loopStart=0,this.loopEnd=0,this._playbackRate=1,this.retrigger=!1,this.onended=function(){},e&&this.load(e,i)},t.extend(t.Player,t.Source),t.Player.prototype.load=function(t,e){if(this._buffer)e&&e(this);else{var i=new XMLHttpRequest;i.open("GET",t,!0),i.responseType="arraybuffer";var n=this;i.onload=function(){n.context.decodeAudioData(i.response,function(t){n.setBuffer(t),e&&e(n)})},i.send()}},t.Player.prototype.setBuffer=function(t){this._buffer=t,this.duration=t.duration},t.Player.prototype.start=function(e,i,n){(this.state===t.Source.State.STOPPED||this.retrigger)&&this._buffer&&(this.state=t.Source.State.STARTED,i=this.defaultArg(i,0),this.loop&&(i=this.loopStart),n=this.defaultArg(n,this._buffer.duration-i),this._source=this.context.createBufferSource(),this._source.buffer=this._buffer,this._source.loop=this.loop,this._source.loopStart=this.loopStart,this._source.loopEnd=this.loopEnd,this._source.playbackRate.value=this._playbackRate,this._source.onended=this._onended.bind(this),this.chain(this._source,this.output),this._source.start(this.toSeconds(e),this.toSeconds(i),this.toSeconds(n)))},t.Player.prototype.stop=function(e){this.state===t.Source.State.STARTED&&this._buffer&&this._source&&(e||(this.state=t.Source.State.STOPPED),this._source.stop(this.toSeconds(e)))},t.Player.prototype.setPlaybackRate=function(t,e){this._playbackRate=t,this._source&&(e?this._source.playbackRate.exponentialRampToValueAtTime(t,this.toSeconds(e)):this._source.playbackRate.value=e)},t.Player.prototype._onended=function(){this.state=t.Source.State.STOPPED,this.onended()},t.Player.prototype.dispose=function(){t.Source.prototype.dispose.call(this),null!==this._source&&(this._source.disconnect(),this._source=null),this._buffer=null},t.Player}),define("Tone/instrument/Sampler",["Tone/core/Tone","Tone/source/Player","Tone/component/AmplitudeEnvelope","Tone/component/Filter","Tone/instrument/Instrument"],function(t){return t.Sampler=function(){t.Instrument.call(this);var e=this.optionsObject(arguments,["url","load"],t.Sampler.defaults);this.player=new t.Player(e.url,e.load),this.player.retrigger=!0,this.envelope=new t.AmplitudeEnvelope(e.envelope),this.filterEnvelope=new t.Envelope(e.filterEnvelope),this.filter=new t.Filter(e.filter),this.chain(this.player,this.filter,this.envelope,this.output),this.filterEnvelope.connect(this.filter.frequency)},t.extend(t.Sampler,t.Instrument),t.Sampler.defaults={url:null,load:function(){},envelope:{attack:.001,decay:0,sustain:1,release:.1},filterEnvelope:{attack:.001,decay:.001,sustain:1,release:.5,min:20,max:2e4},filter:{type:"lowpass"}},t.Sampler.prototype.set=function(t){this.isUndef(t.filterEnvelope)||this.filterEnvelope.set(t.filterEnvelope),this.isUndef(t.envelope)||this.envelope.set(t.envelope),this.isUndef(t.filter)||this.filter.set(t.filter)},t.Sampler.prototype.triggerAttack=function(t,e,i){e=this.toSeconds(e),t=this.defaultArg(t,0),this.player.setPlaybackRate(this.intervalToFrequencyRatio(t),e),this.player.start(e),this.envelope.triggerAttack(e,i),this.filterEnvelope.triggerAttack(e)},t.Sampler.prototype.triggerRelease=function(t){t=this.toSeconds(t),this.filterEnvelope.triggerRelease(t),this.envelope.triggerRelease(t)},t.Sampler.prototype.dispose=function(){t.Instrument.prototype.dispose.call(this),this.player.dispose(),this.filterEnvelope.dispose(),this.envelope.dispose(),this.filter.dispose(),this.player=null,this.filterEnvelope=null,this.envelope=null,this.filter=null},t.Sampler}),define("Tone/instrument/MultiSampler",["Tone/core/Tone","Tone/instrument/Sampler","Tone/instrument/Instrument"],function(t){return t.MultiSampler=function(e,i){t.Instrument.call(this),this.samples={},this._createSamples(e,i)},t.extend(t.MultiSampler,t.Instrument),t.MultiSampler.prototype._createSamples=function(e,i){var n={total:0,loaded:0};for(var o in e)"string"==typeof e[o]&&n.total++;var s=function(){n.loaded++,n.loaded===n.total&&i&&i()};for(var r in e){var a=e[r],c=new t.Sampler(a,s);c.connect(this.output),this.samples[r]=c}},t.MultiSampler.prototype.triggerAttack=function(t,e,i){this.samples.hasOwnProperty(t)&&this.samples[t].triggerAttack(0,e,i)},t.MultiSampler.prototype.triggerRelease=function(t,e){this.samples.hasOwnProperty(t)&&this.samples[t].triggerRelease(e)},t.MultiSampler.prototype.triggerAttackRelease=function(t,e,i,n){if(this.samples.hasOwnProperty(t)){i=this.toSeconds(i),e=this.toSeconds(e);var o=this.samples[t];o.triggerAttack(0,i,n),o.triggerRelease(i+e)}},t.MultiSampler.prototype.set=function(t){for(var e in this.samples)this.samples[e].set(t)},t.MultiSampler.prototype.setVolume=t.Source.prototype.setVolume,t.MultiSampler.prototype.dispose=function(){t.Instrument.prototype.dispose.call(this);for(var e in this.samples)this.samples[e].dispose(),this.samples[e]=null;this.samples=null +},t.MultiSampler}),define("Tone/source/Noise",["Tone/core/Tone","Tone/source/Source"],function(t){t.Noise=function(e){t.Source.call(this),this._source=null,this._buffer=null,this.onended=function(){},this.setType(this.defaultArg(e,"white"))},t.extend(t.Noise,t.Source),t.Noise.prototype.setType=function(o,s){switch(o){case"white":this._buffer=n;break;case"pink":this._buffer=e;break;case"brown":this._buffer=i;break;default:this._buffer=n}this.state===t.Source.State.STARTED&&(s=this.toSeconds(s),this._source.onended=void 0,this._stop(s),this._start(s))},t.Noise.prototype._start=function(t){this._source=this.context.createBufferSource(),this._source.buffer=this._buffer,this._source.loop=!0,this.chain(this._source,this.output),this._source.start(this.toSeconds(t)),this._source.onended=this._onended.bind(this)},t.Noise.prototype.start=function(e){this.state===t.Source.State.STOPPED&&(this.state=t.Source.State.STARTED,this._start(e))},t.Noise.prototype._stop=function(t){this._source.stop(this.toSeconds(t))},t.Noise.prototype.stop=function(e){this.state===t.Source.State.STARTED&&this._buffer&&this._source&&(e||(this.state=t.Source.State.STOPPED),this._stop(e))},t.Noise.prototype._onended=function(){this.state=t.Source.State.STOPPED,this.onended()},t.Noise.prototype.dispose=function(){t.Source.prototype.dispose.call(this),null!==this._source&&(this._source.disconnect(),this._source=null),this._buffer=null};var e=null,i=null,n=null;return t._initAudioContext(function(t){var o=t.sampleRate,s=4*o;e=function(){for(var e=t.createBuffer(2,s,o),i=0;if;f++){var d=2*Math.random()-1;n=.99886*n+.0555179*d,r=.99332*r+.0750759*d,a=.969*a+.153852*d,c=.8665*c+.3104856*d,l=.55*l+.5329522*d,h=-.7616*h-.016898*d,p[f]=n+r+a+c+l+h+u+.5362*d,p[f]*=.11,u=.115926*d}}return e}(),i=function(){for(var e=t.createBuffer(2,s,o),i=0;ia;a++){var c=2*Math.random()-1;n[a]=(r+.02*c)/1.02,r=n[a],n[a]*=3.5}return e}(),n=function(){for(var e=t.createBuffer(2,s,o),i=0;ir;r++)n[r]=2*Math.random()-1;return e}()}),t.Noise}),define("Tone/instrument/PluckSynth",["Tone/core/Tone","Tone/instrument/Instrument","Tone/source/Noise","Tone/component/LowpassCombFilter"],function(t){return t.PluckSynth=function(){t.Instrument.call(this),this._noise=new t.Noise("pink"),this.attackNoise=1,this._lfcf=new t.LowpassCombFilter(1/440),this.resonance=this._lfcf.resonance,this.dampening=this._lfcf.dampening,this._noise.connect(this._lfcf),this._lfcf.connect(this.output)},t.extend(t.PluckSynth,t.Instrument),t.PluckSynth.prototype.triggerAttack=function(t,e){"string"==typeof t&&(t=this.noteToFrequency(t)),e=this.toSeconds(e);var i=1/t;this._lfcf.setDelayTime(i,e),this._noise.start(e),this._noise.stop(e+i*this.attackNoise)},t.PluckSynth.prototype.dispose=function(){t.Instrument.prototype.dispose.call(this),this._noise.dispose(),this._lfcf.dispose(),this._noise=null,this._lfcf=null,this.dampening=null,this.resonance=null},t.PluckSynth}),define("Tone/instrument/PolySynth",["Tone/core/Tone","Tone/instrument/MonoSynth","Tone/source/Source"],function(t){return t.PolySynth=function(){t.Instrument.call(this);var e=this.optionsObject(arguments,["polyphony","voice","voiceOptions"],t.PolySynth.defaults);this._voices=new Array(e.polyphony),this._freeVoices=[],this._activeVoices={};for(var i=0;i0){var o=this._freeVoices.shift();o.triggerAttack(t,e,i),this._activeVoices[n]=o}},t.PolySynth.prototype.triggerAttackRelease=function(t,e,i,n){i=this.toSeconds(i),this.triggerAttack(t,i,n),this.triggerRelease(t,i+this.toSeconds(e))},t.PolySynth.prototype.triggerRelease=function(t,e){var i=JSON.stringify(t),n=this._activeVoices[i];n&&(n.triggerRelease(e),this._freeVoices.push(n),this._activeVoices[i]=null)},t.PolySynth.prototype.set=function(t){for(var e=0;ei){var n=e;e=i,i=n}this._min=new t.Min(i),this._max=new t.Max(e),this.chain(this.input,this._min,this._max,this.output)},t.extend(t.Clip),t.Clip.prototype.setMin=function(t){this._min.setMin(t)},t.Clip.prototype.setMax=function(t){this._max.setMax(t)},t.Clip.prototype.connect=t.Signal.prototype.connect,t.Clip.prototype.dispose=function(){t.prototype.dispose.call(this),this._min.dispose(),this._max.dispose(),this._min=null,this._max=null},t.Clip}),define("Tone/signal/Route",["Tone/core/Tone","Tone/signal/Equal","Tone/signal/Signal"],function(t){t.Route=function(i){i=this.defaultArg(i,2),this.output=new Array(i),this.input=this.context.createGain(),this.gate=new t.Signal(0);for(var n=0;i>n;n++){var o=new e(n);this.output[n]=o,this.gate.connect(o.selecter),this.input.connect(o)}},t.extend(t.Route),t.Route.prototype.select=function(t,e){t=Math.floor(t),this.gate.setValueAtTime(t,this.toSeconds(e))},t.Route.prototype.connect=t.Signal.prototype.connect,t.Route.prototype.dispose=function(){this.gate.dispose();for(var e=0;ei;i++)e[i]=-1,e[i+128]=1;return t.PulseOscillator=function(i,n){t.Source.call(this),this.width=new t.Signal(this.defaultArg(n,.5)),this._sawtooth=new t.Oscillator(i,"sawtooth"),this.frequency=this._sawtooth.frequency,this.detune=this._sawtooth.detune,this._thresh=this.context.createWaveShaper(),this._thresh.curve=e,this.chain(this._sawtooth,this._thresh,this.output),this.width.connect(this._thresh)},t.extend(t.PulseOscillator,t.Source),t.PulseOscillator.prototype.setWidth=function(t){this.width.setValue(t)},t.PulseOscillator.prototype.start=function(e){this.state===t.Source.State.STOPPED&&(e=this.toSeconds(e),this._sawtooth.start(e),this.width.output.gain.setValueAtTime(1,e),this.state=t.Source.State.STARTED)},t.PulseOscillator.prototype.stop=function(e){this.state===t.Source.State.STARTED&&(e=this.toSeconds(e),this._sawtooth.stop(e),this.width.output.gain.setValueAtTime(0,e),this.state=t.Source.State.STOPPED)},t.PulseOscillator.prototype.dispose=function(){t.Source.prototype.dispose.call(this),this._sawtooth.dispose(),this.width.dispose(),this._thresh.disconnect(),this._sawtooth=null,this.frequency=null,this.detune=null,this.width=null,this._thresh=null},t.PulseOscillator}) \ No newline at end of file