diff --git a/.gitignore b/.gitignore index 0c194fbd..263ab8ca 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ examples/scratch.html *.sublime-workspace *.sublime-project + +build/node_modules/* diff --git a/Tone.js b/Tone.js new file mode 100644 index 00000000..f246ea85 --- /dev/null +++ b/Tone.js @@ -0,0 +1,3291 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// TONE.js +// +// @author Yotam Mann +// +// The MIT License (MIT) 2014 +/////////////////////////////////////////////////////////////////////////////// + +(function (root, factory) { + //can run with or without requirejs + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define("Tone/core/Tone",[],function () { + var Tone = factory(root); + return Tone; + }); + } else if (typeof root.Tone !== "function") { + //make Tone public + root.Tone = factory(root); + //define 'define' to invoke the callbacks with Tone + root.define = function(name, deps, func){ + func(root.Tone); + }; + } +} (this, function (global) { + + ////////////////////////////////////////////////////////////////////////// + // WEB AUDIO CONTEXT + /////////////////////////////////////////////////////////////////////////// + + //ALIAS + if (!global.AudioContext){ + global.AudioContext = global.webkitAudioContext; + } + + var audioContext; + if (global.AudioContext){ + audioContext = new global.AudioContext(); + } + + //SHIMS//////////////////////////////////////////////////////////////////// + + if (typeof audioContext.createGain !== "function"){ + audioContext.createGain = audioContext.createGainNode; + } + if (typeof audioContext.createDelay !== "function"){ + audioContext.createDelay = audioContext.createDelayNode; + } + + if (typeof AudioBufferSourceNode.prototype.start !== "function"){ + AudioBufferSourceNode.prototype.start = AudioBufferSourceNode.prototype.noteGrainOn; + } + if (typeof AudioBufferSourceNode.prototype.stop !== "function"){ + AudioBufferSourceNode.prototype.stop = AudioBufferSourceNode.prototype.noteOff; + } + if (typeof OscillatorNode.prototype.start !== "function"){ + OscillatorNode.prototype.start = OscillatorNode.prototype.noteOn; + } + if (typeof OscillatorNode.prototype.stop !== "function"){ + OscillatorNode.prototype.stop = OscillatorNode.prototype.noteOff; + } + //extend the connect function to include Tones + AudioNode.prototype._nativeConnect = AudioNode.prototype.connect; + AudioNode.prototype.connect = function(B){ + if (B.input && B.input instanceof GainNode){ + this._nativeConnect(B.input); + } else { + try { + this._nativeConnect.apply(this, arguments); + } catch (e) { + throw new Error("trying to connect to a node with no inputs"); + } + } + }; + + /////////////////////////////////////////////////////////////////////////// + // TONE + // @constructor + /////////////////////////////////////////////////////////////////////////// + + /** + * Tone is the baseclass of all ToneNodes + * From Tone, children inherit timing and math which is used throughout Tone.js + * + * @constructor + */ + var Tone = function(){ + /** + * default input of the ToneNode + * + * @type {GainNode} + */ + this.input = audioContext.createGain(); + /** + * default output of the ToneNode + * + * @type {GainNode} + */ + this.output = audioContext.createGain(); + }; + + /////////////////////////////////////////////////////////////////////////// + // CLASS VARS + /////////////////////////////////////////////////////////////////////////// + + /** + * A pointer to the audio context + * @type {AudioContext} + */ + Tone.prototype.context = audioContext; + + /** + * A static pointer to the audio context + * @type {AudioContext} + */ + Tone.context = audioContext; + + /** + * the default buffer size + * @type {number} + */ + Tone.prototype.bufferSize = 2048; + + /** + * the default resolution for WaveShaperNodes + * @type {number} + */ + Tone.prototype.waveShaperResolution = 1024; + + /////////////////////////////////////////////////////////////////////////// + // CONNECTIONS + /////////////////////////////////////////////////////////////////////////// + + /** + * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode + * @param {Tone | AudioParam | AudioNode} unit + */ + Tone.prototype.connect = function(unit){ + this.output.connect(unit); + }; + + /** + * disconnect the output + */ + Tone.prototype.disconnect = function(){ + this.output.disconnect(); + }; + + /** + * connect together all of the arguments in series + * @param {...AudioParam|Tone} + */ + Tone.prototype.chain = function(){ + if (arguments.length > 1){ + var currentUnit = arguments[0]; + for (var i = 1; i < arguments.length; i++){ + var toUnit = arguments[i]; + currentUnit.connect(toUnit); + currentUnit = toUnit; + } + } + }; + + /////////////////////////////////////////////////////////////////////////// + // UTILITIES / HELPERS / MATHS + /////////////////////////////////////////////////////////////////////////// + + //borrowed from underscore.js + function isUndef(val){ + return val === void 0; + } + + /** + * if a the given is undefined, use the fallback + * + * @param {*} given + * @param {*} fallback + * @return {*} + */ + Tone.prototype.defaultArg = function(given, fallback){ + return isUndef(given) ? fallback : given; + }; + + /** + * equal power gain scale + * good for cross-fading + * + * @param {number} percent (0-1) + * @return {number} output gain (0-1) + */ + Tone.prototype.equalPowerScale = function(percent){ + var piFactor = 0.5 * Math.PI; + return Math.sin(percent * piFactor); + }; + + /** + * @param {number} gain (0-1) + * @return {number} gain (decibel scale but betwee 0-1) + */ + Tone.prototype.logScale = function(gain) { + return Math.max(this.normalize(this.gainToDb(gain), -100, 0), 0); + }; + + /** + * @param {number} gain (0-1) + * @return {number} gain (decibel scale but betwee 0-1) + */ + Tone.prototype.expScale = function(gain) { + return this.dbToGain(this.interpolate(gain, -100, 0)); + }; + + /** + * convert db scale to gain scale (0-1) + * @param {number} db + * @return {number} + */ + Tone.prototype.dbToGain = function(db) { + return Math.pow(2, db / 6); + }; + + /** + * convert gain scale to decibels + * @param {number} gain (0-1) + * @return {number} + */ + Tone.prototype.gainToDb = function(gain) { + return 20 * (Math.log(gain) / Math.LN10); + }; + + /** + * interpolate the input value (0-1) to be between outputMin and outputMax + * @param {number} input + * @param {number} outputMin + * @param {number} outputMax + * @return {number} + */ + Tone.prototype.interpolate = function(input, outputMin, outputMax){ + return input*(outputMax - outputMin) + outputMin; + }; + + /** + * normalize the input to 0-1 from between inputMin to inputMax + * @param {number} input + * @param {number} inputMin + * @param {number} inputMax + * @return {number} + */ + Tone.prototype.normalize = function(input, inputMin, inputMax){ + //make sure that min < max + if (inputMin > inputMax){ + var tmp = inputMax; + inputMax = inputMin; + inputMin = tmp; + } else if (inputMin == inputMax){ + return 0; + } + return (input - inputMin) / (inputMax - inputMin); + }; + + + /////////////////////////////////////////////////////////////////////////// + // TIMING + /////////////////////////////////////////////////////////////////////////// + + /** + * @return {number} the currentTime from the AudioContext + */ + Tone.prototype.now = function(){ + return audioContext.currentTime; + }; + + /** + * convert a sample count to seconds + * @param {number} samples + * @return {number} + */ + Tone.prototype.samplesToSeconds = function(samples){ + return samples / audioContext.sampleRate; + }; + + /** + * convert a time into samples + * + * @param {Tone.time} time + * @return {number} + */ + Tone.prototype.toSamples = function(time){ + var seconds = this.toSeconds(time); + return seconds * audioContext.sampleRate; + }; + + /** + * convert Tone.Time to seconds + * + * this is a simplified version which only handles numbers and + * 'now' relative numbers. If the Transport is included this + * method is overridden to include many other features including + * notationTime, Frequency, and transportTime + * + * @param {Tone.Time} time + * @return {number} + */ + Tone.prototype.toSeconds = function(time){ + if (typeof time === "number"){ + return time; //assuming that it's seconds + } else if (typeof time === "string"){ + var plusTime = 0; + if(time.charAt(0) === "+") { + plusTime = this.now(); + time = time.slice(1); + } + return parseFloat(time) + plusTime; + } else { + return this.now(); + } + }; + + + /** + * convert a frequency into seconds + * accepts both numbers and strings + * i.e. 10hz or 10 both equal .1 + * + * @param {number|string} freq + * @return {number} + */ + Tone.prototype.frequencyToSeconds = function(freq){ + return 1 / parseFloat(freq); + }; + + /** + * convert a number in seconds to a frequency + * @param {number} seconds + * @return {number} + */ + Tone.prototype.secondsToFrequency = function(seconds){ + return 1/seconds; + }; + + /////////////////////////////////////////////////////////////////////////// + // STATIC METHODS + /////////////////////////////////////////////////////////////////////////// + + /** + * have a child inherit all of Tone's (or a parent's) prototype + * to inherit the parent's properties, make sure to call + * Parent.call(this) in the child's constructor + * + * based on closure library's inherit function + * + * @param {function} child + * @param {function=} parent (optional) parent to inherit from + * if no parent is supplied, the child + * will inherit from Tone + */ + Tone.extend = function(child, parent){ + if (isUndef(parent)){ + parent = Tone; + } + function tempConstructor(){} + tempConstructor.prototype = parent.prototype; + child.prototype = new tempConstructor(); + /** @override */ + child.prototype.constructor = child; + }; + + return Tone; +})); + +define('Tone/signal/Signal',["Tone/core/Tone"], function(Tone){ + + //all signals share a common constant signal generator + /** + * @static + * @private + * @type {OscillatorNode} + */ + var generator = Tone.context.createOscillator(); + + /** + * @static + * @private + * @type {WaveShaperNode} + */ + var constant = Tone.context.createWaveShaper(); + + //generate the waveshaper table which outputs 1 for any input value + (function(){ + var len = 8; + var curve = new Float32Array(len); + for (var i = 0; i < len; i++){ + //all inputs produce the output value + curve[i] = 1; + } + constant.curve = curve; + })(); + + generator.connect(constant); + generator.start(0); + + /** + * constant audio-rate signal + * + * Tone.Signal is a core component which allows for synchronization of many components. + * A single signal can drive multiple parameters by applying Scaling. + * + * For example: to synchronize two Tone.Oscillators in octaves of each other, + * Signal --> OscillatorA.frequency + * ^--> Tone.Multiply(2) --> OscillatorB.frequency + * + * + * Tone.Signal can be scheduled with all of the functions available to AudioParams + * + * + * @constructor + * @param {number=} value (optional) initial value + */ + Tone.Signal = function(value){ + /** + * scales the constant output to the desired output + * @type {GainNode} + */ + this.scalar = this.context.createGain(); + /** + * the output node + * @type {GainNode} + */ + this.output = this.context.createGain(); + /** + * the ratio of the this value to the control signal value + * + * @private + * @type {number} + */ + this._syncRatio = 1; + + //connect the constant 1 output to the node output + this.chain(constant, this.scalar, this.output); + + //set the default value + this.setValue(this.defaultArg(value, 0)); + + }; + + Tone.extend(Tone.Signal); + + /** + * @return {number} the current value of the signal + */ + Tone.Signal.prototype.getValue = function(){ + return this.scalar.gain.value; + }; + + /** + * set the value of the signal right away + * will be overwritten if there are previously scheduled automation curves + * + * @param {number} value + */ + Tone.Signal.prototype.setValue = function(value){ + if (this._syncRatio === 0){ + value = 0; + } else { + value *= this._syncRatio; + } + this.scalar.gain.value = value; + }; + + /** + * Schedules a parameter value change at the given time. + * + * @param {number} value + * @param {Tone.Time} time + */ + Tone.Signal.prototype.setValueAtTime = function(value, time){ + value *= this._syncRatio; + this.scalar.gain.setValueAtTime(value, this.toSeconds(time)); + }; + + /** + * creates a schedule point with the current value at the current time + * + * @returns {number} the current value + */ + Tone.Signal.prototype.setCurrentValueNow = function(){ + var now = this.now(); + var currentVal = this.getValue(); + this.cancelScheduledValues(now); + this.scalar.gain.setValueAtTime(currentVal, now); + return currentVal; + }; + + /** + * Schedules a linear continuous change in parameter value from the + * previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Tone.Time} endTime + */ + Tone.Signal.prototype.linearRampToValueAtTime = function(value, endTime){ + value *= this._syncRatio; + this.scalar.gain.linearRampToValueAtTime(value, this.toSeconds(endTime)); + }; + + /** + * Schedules an exponential continuous change in parameter value from + * the previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Tone.Time} endTime + */ + Tone.Signal.prototype.exponentialRampToValueAtTime = function(value, endTime){ + value *= this._syncRatio; + this.scalar.gain.exponentialRampToValueAtTime(value, this.toSeconds(endTime)); + }; + + /** + * Schedules an exponential continuous change in parameter value from + * the current time and current value to the given value. + * + * @param {number} value + * @param {Tone.Time} endTime + */ + Tone.Signal.prototype.exponentialRampToValueNow = function(value, endTime){ + this.setCurrentValueNow(); + value *= this._syncRatio; + //make sure that the endTime doesn't start with + + if (endTime.toString().charAt(0) === "+"){ + endTime = endTime.substr(1); + } + this.scalar.gain.exponentialRampToValueAtTime(value, this.now() + this.toSeconds(endTime)); + }; + + /** + * Schedules an linear continuous change in parameter value from + * the current time and current value to the given value at the given time. + * + * @param {number} value + * @param {Tone.Time} endTime + */ + Tone.Signal.prototype.linearRampToValueNow = function(value, endTime){ + this.setCurrentValueNow(); + value *= this._syncRatio; + //make sure that the endTime doesn't start with + + if (endTime.toString().charAt(0) === "+"){ + endTime = endTime.substr(1); + } + this.scalar.gain.linearRampToValueAtTime(value, this.now() + this.toSeconds(endTime)); + }; + + /** + * Start exponentially approaching the target value at the given time with + * a rate having the given time constant. + * + * @param {number} value + * @param {Tone.Time} startTime + * @param {number} timeConstant + */ + Tone.Signal.prototype.setTargetAtTime = function(value, startTime, timeConstant){ + value *= this._syncRatio; + this.output.gain.setTargetAtTime(value, this.toSeconds(startTime), timeConstant); + }; + + /** + * Sets an array of arbitrary parameter values starting at the given time + * for the given duration. + * + * @param {Array} values + * @param {Tone.Time} startTime + * @param {Tone.Time} duration + */ + Tone.Signal.prototype.setValueCurveAtTime = function(values, startTime, duration){ + for (var i = 0; i < values.length; i++){ + values[i] *= this._syncRatio; + } + this.scalar.gain.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration)); + }; + + /** + * Cancels all scheduled parameter changes with times greater than or + * equal to startTime. + * + * @param {Tone.Time} startTime + */ + Tone.Signal.prototype.cancelScheduledValues = function(startTime){ + this.scalar.gain.cancelScheduledValues(this.toSeconds(startTime)); + }; + + /** + * Sync this to another signal and it will always maintain the + * ratio between the two signals until it is unsynced + * + * @param {Tone.Signal} signal to sync to + */ + Tone.Signal.prototype.sync = function(signal){ + //get the sync ratio + if (signal.getValue() !== 0){ + this._syncRatio = this.getValue() / signal.getValue(); + } else { + this._syncRatio = 0; + } + //make a new scalar which is not connected to the constant signal + this.scalar.disconnect(); + this.scalar = this.context.createGain(); + this.chain(signal, this.scalar, this.output); + //set it ot the sync ratio + this.scalar.gain.value = this._syncRatio; + }; + + /** + * unbind the signal control + * + * will leave the signal value as it was without the influence of the control signal + */ + Tone.Signal.prototype.unsync = function(){ + //make a new scalar so that it's disconnected from the control signal + //get the current gain + var currentGain = this.getValue(); + this.scalar.disconnect(); + this.scalar = this.context.createGain(); + this.scalar.gain.value = currentGain / this._syncRatio; + this._syncRatio = 1; + //reconnect things up + this.chain(constant, this.scalar, this.output); + }; + + return Tone.Signal; +}); +define('Tone/signal/Add',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ + + /** + * Adds a value to an incoming signal + * + * @constructor + * @extends {Tone} + * @param {number} value + */ + Tone.Add = function(value){ + Tone.call(this); + + /** + * @private + * @type {Tone} + */ + this._value = new Tone.Signal(value); + + //connections + this.chain(this._value, this.input, this.output); + }; + + Tone.extend(Tone.Add); + + /** + * set the constant + * + * @param {number} value + */ + Tone.Add.prototype.setValue = function(value){ + this._value.setValue(value); + }; + + return Tone.Add; +}); +define('Tone/signal/Multiply',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ + + /** + * Multiply the incoming signal by some factor + * + * @constructor + * @extends {Tone} + * @param {number=} value constant value to multiple + */ + Tone.Multiply = function(value){ + /** + * the input node is the same as the output node + * it is also the GainNode which handles the scaling of incoming signal + * + * @type {GainNode} + */ + this.input = this.context.createGain(); + /** @alias {GainNode} */ + this.output = this.input; + + //apply the inital scale factor + this.input.gain.value = this.defaultArg(value, 1); + }; + + Tone.extend(Tone.Multiply); + + /** + * set the constant multiple + * + * @param {number} value + */ + Tone.Multiply.prototype.setValue = function(value){ + this.input.gain.value = value; + }; + + return Tone.Multiply; +}); + +define('Tone/signal/Scale',["Tone/core/Tone", "Tone/signal/Add", "Tone/signal/Multiply"], function(Tone){ + + /** + * performs a linear scaling on an input signal + * + * scales from the input range of inputMin to inputMax + * to the output range of outputMin to outputMax + * + * 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 + */ + Tone.Scale = function(inputMin, inputMax, outputMin, outputMax){ + Tone.call(this); + + //if there are only two args + if (arguments.length == 2){ + 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._scale = new Tone.Multiply(1); + /** @private + @type {Tone.Add} */ + this._plusOutput = new Tone.Add(0); + + //connections + this.chain(this.input, this._plusInput, this._scale, this._plusOutput, this.output); + + //set the scaling values + this._setScalingParameters(); + }; + + Tone.extend(Tone.Scale); + + /** + * set the scaling parameters + * + * @private + */ + Tone.Scale.prototype._setScalingParameters = function(){ + //components + this._plusInput.setValue(-this._inputMin); + this._scale.setValue((this._outputMax - this._outputMin)/(this._inputMax - this._inputMin)); + this._plusOutput.setValue(this._outputMin); + }; + + /** + * set the input min value + * @param {number} val + */ + Tone.Scale.prototype.setInputMin = function(val){ + this._inputMin = val; + this._setScalingParameters(); + }; + + /** + * set the input max value + * @param {number} val + */ + Tone.Scale.prototype.setInputMax = function(val){ + this._inputMax = val; + this._setScalingParameters(); + }; + + /** + * set the output min value + * @param {number} val + */ + Tone.Scale.prototype.setOutputMin = function(val){ + this._outputMin = val; + this._setScalingParameters(); + }; + + /** + * set the output max value + * @param {number} val + */ + Tone.Scale.prototype.setOutputMax = function(val){ + this._outputMax = val; + this._setScalingParameters(); + }; + + return Tone.Scale; +}); + +define('Tone/component/DryWet',["Tone/core/Tone", "Tone/signal/Signal", "Tone/signal/Scale"], function(Tone){ + + /** + * DRY/WET KNOB + * + * equal power fading control values: + * 0 = 100% dry + * 1 = 100% wet + * + * @constructor + * @param {number} initialDry + */ + Tone.DryWet = function(initialDry){ + Tone.call(this); + + //components + this.dry = this.context.createGain(); + this.wet = this.context.createGain(); + //control signal + this.control = new Tone.Signal(); + this.invert = new Tone.Scale(1, 0); + this.normal = new Tone.Scale(0, 1); + + //connections + this.dry.connect(this.output); + this.wet.connect(this.output); + //wet control + this.chain(this.control, this.invert, this.wet.gain); + //dry control + this.chain(this.control, this.normal, this.dry.gain); + + //setup + this.dry.gain.value = 0; + this.wet.gain.value = 0; + this.setDry(0); + }; + + Tone.extend(Tone.DryWet); + + /** + * Set the dry value of the knob + * + * @param {number} val + * @param {Tone.Time} rampTime + */ + Tone.DryWet.prototype.setDry = function(val, rampTime){ + rampTime = this.defaultArg(rampTime, 0); + this.control.linearRampToValueAtTime(val*2 - 1, this.toSeconds(rampTime)); + }; + + /** + * Set the wet value of the knob + * + * @param {number} val + * @param {Tone.Time} rampTime + */ + Tone.DryWet.prototype.setWet = function(val, rampTime){ + this.setDry(1-val, rampTime); + }; + + return Tone.DryWet; +}); + +define('Tone/component/Envelope',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ + + /** + * Envelope + * ADR envelope generator attaches to an AudioParam + * + * @constructor + * @extends {Tone} + * @param {Tone.Time=} attack + * @param {Tone.Time=} decay + * @param {number=} sustain a percentage (0-1) of the full amplitude + * @param {Tone.Time=} release + * @param {number=} minOutput the lowest point of the envelope + * @param {number=} maxOutput the highest point of the envelope + */ + Tone.Envelope = function(attack, decay, sustain, release, minOutput, maxOutput){ + //extend Unit + Tone.call(this); + + //set the parameters + this.attack = this.defaultArg(attack, 0.01); + this.decay = this.defaultArg(decay, 0.1); + this.release = this.defaultArg(release, 1); + this.sustain = this.defaultArg(sustain, 0.5); + + this.min = this.defaultArg(minOutput, 0); + this.max = this.defaultArg(maxOutput, 1); + + //the control signal + this.control = new Tone.Signal(this.min); + + //connections + this.chain(this.control, this.output); + }; + + Tone.extend(Tone.Envelope); + + /** + * attack->decay->sustain linear ramp + * @param {Tone.Time} time + */ + Tone.Envelope.prototype.triggerAttack = function(time){ + var startVal = this.min; + if (!time){ + startVal = this.control.getValue(); + } + time = this.defaultArg(time, this.now()); + time = this.toSeconds(time); + this.control.cancelScheduledValues(time); + this.control.setValueAtTime(startVal, time); + var attackTime = this.toSeconds(this.attack); + var decayTime = this.toSeconds(this.decay); + this.control.linearRampToValueAtTime(this.max, time + attackTime); + var sustainVal = (this.max - this.min) * this.sustain + this.min; + this.control.linearRampToValueAtTime(sustainVal, time + attackTime + decayTime); + }; + + /** + * attack->decay->sustain exponential ramp + * @param {Tone.Time} time + */ + Tone.Envelope.prototype.triggerAttackExp = function(time){ + var startVal = this.min; + if (!time){ + startVal = this.control.getValue(); + } + time = this.toSeconds(time); + this.control.cancelScheduledValues(time); + this.control.setValueAtTime(startVal, time); + var attackTime = this.toSeconds(this.attack); + var decayTime = this.toSeconds(this.decay); + this.control.linearRampToValueAtTime(this.max, time + attackTime); + var sustainVal = (this.max - this.min) * this.sustain + this.min; + this.control.exponentialRampToValueAtTime(sustainVal, time + attackTime + decayTime); + }; + + + /** + * triggers the release of the envelope with a linear ramp + * @param {Tone.Time} time + */ + Tone.Envelope.prototype.triggerRelease = function(time){ + var startVal = this.control.getValue(); + if (time){ + startVal = (this.max - this.min) * this.sustain + this.min; + } + time = this.toSeconds(time); + this.control.cancelScheduledValues(time); + this.control.setValueAtTime(startVal, time); + this.control.linearRampToValueAtTime(this.min, time + this.toSeconds(this.release)); + }; + + + /** + * triggers the release of the envelope with an exponential ramp + * + * @param {Tone.Time} time + */ + Tone.Envelope.prototype.triggerReleaseExp = function(time){ + var startVal = this.control.getValue(); + if (time){ + startVal = (this.max - this.min) * this.sustain + this.min; + } + time = this.toSeconds(time); + this.control.cancelScheduledValues(time); + this.control.setValueAtTime(startVal, time); + this.control.exponentialRampToValueAtTime(this.min, time + this.toSeconds(this.release)); + }; + + /** + * pointer to the parent's connect method + * @private + */ + Tone.Envelope.prototype._connect = Tone.prototype.connect; + + /** + * connect the envelope + * + * if the envelope is connected to a param, the params + * value will be set to 0 so that it doesn't interfere with the envelope + * + * @param {number} param + */ + Tone.Envelope.prototype.connect = function(param){ + if (param instanceof AudioParam){ + //set the initial value + param.value = 0; + } + this._connect(param); + }; + + return Tone.Envelope; +}); + +/////////////////////////////////////////////////////////////////////////////// +// +// MASTER OUTPUT +// +// a single master output +// adds a toMaster method on AudioNodes and components +/////////////////////////////////////////////////////////////////////////////// + + +define('Tone/core/Master',["Tone/core/Tone"], function(Tone){ + + var Master = function(){ + //extend audio unit + Tone.call(this); + + //put a hard limiter on the output so we don't blow any eardrums + 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); + } + + Tone.extend(Master); + + /////////////////////////////////////////////////////////////////////////// + // Add toMaster methods + /////////////////////////////////////////////////////////////////////////// + + //@param {AudioNode|Tone=} unit + Tone.prototype.toMaster = function(){ + this.connect(Tone.Master); + } + + AudioNode.prototype.toMaster = function(){ + this.connect(Tone.Master); + } + + //a single master output + Tone.Master = new Master(); + + return Tone.Master; +}); +define('Tone/core/Transport',["Tone/core/Tone", "Tone/core/Master", "Tone/signal/Signal"], +function(Tone){ + + + /** + * oscillator-based transport allows for simple musical timing + * supports tempo curves and time changes + * + * @constructor + */ + Tone.Transport = function(){ + + /** + * watches the main oscillator for timing ticks + * + * @private + * @type {ScriptProcessorNode} + */ + this._jsNode = this.context.createScriptProcessor(this.bufferSize, 1, 1); + this._jsNode.onaudioprocess = this._processBuffer.bind(this); + + /** @type {boolean} */ + this.loop = false; + + //so it doesn't get garbage collected + this._jsNode.toMaster(); + }; + + Tone.extend(Tone.Transport); + + /** + * @private + * @type {number} + */ + var transportTicks = 0; + /** + * @private + * @type {number} + */ + var tatum = 12; + /** + * @private + * @type {Boolean} + */ + var upTick = false; + /** + * @private + * @type {number} + */ + var transportTimeSignature = 4; + + /** + * @private + * @type {number} + */ + var loopStart = 0; + /** + * @private + * @type {number} + */ + var loopEnd = tatum * 4; + + /** + * @private + * @type {Array} + */ + var intervals = []; + /** + * @private + * @type {Array} + */ + var timeouts = []; + /** + * @private + * @type {Array} + */ + var timeline = []; + /** + * @private + * @type {number} + */ + var timelineProgress = 0; + + /** + * The main oscillator for the system + * @private + * @type {OscillatorNode} + */ + var oscillator = null; + + /** + * controls the oscillator frequency + * starts at 120bpm + * @private + * @type {Tone.Signal} + */ + var controlSignal = new Tone.Signal(120); + + /** + * All of the synced components + * @private + * @type {Array} + */ + var SyncedComponents = []; + + + /////////////////////////////////////////////////////////////////////////////// + // JS NODE PROCESSING + /////////////////////////////////////////////////////////////////////////////// + + /** + * called when a buffer is ready + * + * @param {AudioProcessingEvent} event + */ + Tone.Transport.prototype._processBuffer = function(event){ + var now = this.defaultArg(event.playbackTime, this.now()); + var bufferSize = this._jsNode.bufferSize; + var incomingBuffer = event.inputBuffer.getChannelData(0); + for (var i = 0; i < bufferSize; i++){ + var sample = incomingBuffer[i]; + if (sample > 0 && !upTick){ + upTick = true; + this._processTick(now + this.samplesToSeconds(i), i); + } else if (sample < 0 && upTick){ + upTick = false; + } + } + }; + + //@param {number} tickTime + Tone.Transport.prototype._processTick = function(tickTime, i){ + if (oscillator !== null){ + transportTicks += 1; + processIntervals(tickTime); + processTimeouts(tickTime, i); + processTimeline(tickTime); + if (this.loop){ + if (transportTicks === loopEnd){ + this._setTicks(this.loopEnd); + } + } + } + }; + + //jump to a specific tick in the timeline + Tone.Transport.prototype._setTicks = function(ticks){ + transportTicks = ticks; + for (var i = 0; i < timeline.length; i++){ + var timeout = timeline[i]; + if (timeout.callbackTick() >= ticks){ + timelineProgress = i; + break; + } + } + }; + + /////////////////////////////////////////////////////////////////////////////// + // EVENT PROCESSING + /////////////////////////////////////////////////////////////////////////////// + + /** + * process the intervals + * @param {number} time + */ + var processIntervals = function(time){ + for (var i = 0, len = intervals.length; i transportTicks){ + break; + } + } + //remove the timeouts off the front of the array after they've been called + timeouts.splice(0, removeTimeouts); + }; + + /** + * process the timeline events + * @param {number} time + */ + var processTimeline = function(time){ + for (var i = timelineProgress, len = timeline.length; i transportTicks){ + break; + } + } + }; + + /** + * clear the timeouts and intervals + */ + function clearTimelineEvents(){ + timeouts = []; + intervals = []; + } + + /////////////////////////////////////////////////////////////////////////////// + // INTERVAL + /////////////////////////////////////////////////////////////////////////////// + + /** + * intervals are recurring events + * + * @param {function} callback + * @param {Tone.Time} interval + * @param {Object} ctx the context the function is invoked in + * @return {number} the id of the interval + */ + Tone.Transport.prototype.setInterval = function(callback, interval, ctx){ + var tickTime = this.toTicks(interval); + var timeout = new TimelineEvent(callback, ctx, tickTime, transportTicks); + intervals.push(timeout); + return timeout.id; + }; + + /** + * clear an interval from the processing array + * @param {number} rmInterval the interval to remove + * @return {boolean} true if the event was removed + */ + Tone.Transport.prototype.clearInterval = function(rmInterval){ + for (var i = 0; i < intervals.length; i++){ + var interval = intervals[i]; + if (interval.id === rmInterval){ + intervals.splice(i, 1); + return true; + } + } + return false; + }; + + /////////////////////////////////////////////////////////////////////////////// + // TIMEOUT + /////////////////////////////////////////////////////////////////////////////// + + /** + * set a timeout to occur after time from now + * + * @param {function} callback + * @param {Tone.Time} time + * @param {Object} ctx the context to invoke the callback in + * @return {number} the id of the timeout for clearing timeouts + */ + Tone.Transport.prototype.setTimeout = function(callback, time, ctx){ + var ticks = this.toTicks(time); + var timeout = new TimelineEvent(callback, ctx, ticks + transportTicks, 0); + //put it in the right spot + for (var i = 0, len = timeouts.length; i timeout.callbackTick()){ + timeouts.splice(i, 0, timeout); + return timeout.id; + } + } + //otherwise push it on the end + timeouts.push(timeout); + return timeout.id; + }; + + /** + * clear the timeout based on it's ID + * @param {number} timeoutID + * @return {boolean} true if the timeout was removed + */ + Tone.Transport.prototype.clearTimeout = function(timeoutID){ + for (var i = 0; i < timeouts.length; i++){ + var testTimeout = timeouts[i]; + if (testTimeout.id === timeoutID){ + timeouts.splice(i, 1); + return true; + } + } + return false; + }; + + /////////////////////////////////////////////////////////////////////////////// + // TIMELINE + /////////////////////////////////////////////////////////////////////////////// + + /** + * Timeline events are synced to the timeline of the Transport + * Unlike Timeout, Timeline events will restart after the + * Transport has been stopped and restarted. + * + * + * @param {function} callback + * @param {Tome.Time} timeout + * @param {Object} ctx the context in which the funtion is called + * @return {number} the id for clearing the timeline event + */ + Tone.Transport.prototype.setTimeline = function(callback, timeout, ctx){ + var ticks = this.toTicks(timeout); + ctx = this.defaultArg(ctx, window); + var timelineEvnt = new TimelineEvent(callback, ctx, ticks + transportTicks, 0); + //put it in the right spot + for (var i = timelineProgress, len = timeline.length; i timelineEvnt.callbackTick()){ + timeline.splice(i, 0, timelineEvnt); + return timelineEvnt.id; + } + } + //otherwise push it on the end + timeline.push(event); + return timelineEvnt.id; + }; + + /** + * clear the timeline event from the + * @param {number} timelineID + * @return {boolean} true if it was removed + */ + Tone.Transport.prototype.clearTimeline = function(timelineID){ + for (var i = 0; i < timeline.length; i++){ + var testTimeline = timeline[i]; + if (testTimeline.id === timelineID){ + timeline.splice(i, 1); + return true; + } + } + return false; + }; + + /////////////////////////////////////////////////////////////////////////////// + // TIME CONVERSIONS + /////////////////////////////////////////////////////////////////////////////// + + /** + * turns the time into + * @param {Tone.Time} time + * @return {number} + */ + Tone.Transport.prototype.toTicks = function(time){ + //get the seconds + var seconds = this.toSeconds(time); + var quarter = this.notationToSeconds("4n"); + var quarters = seconds / quarter; + var tickNum = quarters * tatum; + //quantize to tick value + return Math.round(tickNum); + }; + + /** + * get the transport time + * @return {string} in transportTime format (measures:beats:sixteenths) + */ + Tone.Transport.prototype.getTransportTime = function(){ + var quarters = transportTicks / tatum; + var measures = Math.floor(quarters / transportTimeSignature); + var sixteenths = Math.floor((quarters % 1) * 4); + quarters = Math.floor(quarters) % transportTimeSignature; + var progress = [measures, quarters, sixteenths]; + return progress.join(":"); + }; + + /** + * set the transport time, jump to the position right away + * + * @param {Tone.Time} progress + */ + Tone.Transport.prototype.setTransportTime = function(progress){ + var ticks = this.toTicks(progress); + this._setTicks(ticks); + }; + + /////////////////////////////////////////////////////////////////////////////// + // START/STOP/PAUSE + /////////////////////////////////////////////////////////////////////////////// + + /** + * start the transport and all sources synced to the transport + * + * @param {Tone.Time} time + */ + Tone.Transport.prototype.start = function(time){ + if (oscillator === null){ + //reset the oscillator + oscillator = this.context.createOscillator(); + oscillator.type = "square"; + oscillator.connect(this._jsNode); + //connect it up + controlSignal.connect(oscillator.frequency); + oscillator.frequency.value = 0; + } + upTick = false; + oscillator.start(this.toSeconds(time)); + //call start on each of the synced sources + }; + + + /** + * stop the transport and all sources synced to the transport + * + * @param {Tone.Time} time + */ + Tone.Transport.prototype.stop = function(time){ + if (oscillator !== null){ + oscillator.stop(this.toSeconds(time)); + oscillator = null; + } + this._setTicks(0); + clearTimelineEvents(); + //call stop on each of the synced sources + }; + + /** + * pause the transport and all sources synced to the transport + * + * @param {Tone.Time} time + */ + Tone.Transport.prototype.pause = function(time){ + oscillator.stop(this.toSeconds(time)); + oscillator = null; + clearTimelineEvents(); + //call pause on each of the synced sources + }; + + /////////////////////////////////////////////////////////////////////////////// + // SETTERS/GETTERS + /////////////////////////////////////////////////////////////////////////////// + + /** + * set the BPM + * optionally ramp to the bpm over some time + * @param {number} bpm + * @param {Tone.Time=} rampTime + */ + Tone.Transport.prototype.setBpm = function(bpm, rampTime){ + //convert the bpm to frequency + var tatumFreq = this.toFrequency(tatum.toString() + "n", bpm, transportTimeSignature); + var freqVal = 4 * tatumFreq; + if (!rampTime){ + controlSignal.cancelScheduledValues(0); + controlSignal.setValue(freqVal); + } else { + controlSignal.exponentialRampToValueNow(freqVal, rampTime); + } + }; + + /** + * return the current BPM + * + * @return {number} + */ + Tone.Transport.prototype.getBpm = function(){ + //convert the current frequency of the oscillator to bpm + var freq = controlSignal.getValue(); + return 60 * (freq / tatum); + }; + + /** + * set the time signature + * + * @example + * this.setTimeSignature(4); //for 4/4 + * + * @param {number} numerator + * @param {number=} denominator defaults to 4 + */ + Tone.Transport.prototype.setTimeSignature = function(numerator, denominator){ + denominator = this.defaultArg(denominator, 4); + transportTimeSignature = numerator / (denominator / 4); + }; + + /** + * return the time signature as just the numerator + * over 4 is assumed. + * for example 4/4 would return 4 and 6/8 would return 3 + * + * @return {number} + */ + Tone.Transport.prototype.getTimeSignature = function(){ + return transportTimeSignature; + }; + + /** + * set the loop start position + * + * @param {Tone.Time} startPosition + */ + Tone.Transport.prototype.setLoopStart = function(startPosition){ + loopStart = this.toTicks(startPosition); + }; + + /** + * set the loop start position + * + * @param {Tone.Time} endPosition + */ + Tone.Transport.prototype.setLoopEnd = function(endPosition){ + loopEnd = this.toTicks(endPosition); + }; + + /** + * shorthand loop setting + * @param {Tone.Time} startPosition + * @param {Tone.Time} endPosition + */ + Tone.Transport.prototype.setLoopPoint = function(startPosition, endPosition){ + this.setLoopStart(startPosition); + this.setLoopEnd(endPosition); + }; + + /////////////////////////////////////////////////////////////////////////////// + // SYNCING + /////////////////////////////////////////////////////////////////////////////// + + + Tone.Transport.prototype.sync = function(source, controlSignal){ + //create a gain node, attach it to the control signal + // var ratio = new Tone.Multiply(); + // controlSignal.connect(ratio); + // return ratio; + }; + + /** + * remove the source from the list of Synced Sources + * + * @param {Tone.Source} source [description] + */ + Tone.Transport.prototype.unsync = function(source){ + + }; + + + /////////////////////////////////////////////////////////////////////////////// + // TIMELINE EVENT + /////////////////////////////////////////////////////////////////////////////// + + /** + * @static + * @type {number} + */ + var TimelineEventIDCounter = 0; + + /** + * A Timeline event + * + * @constructor + * @param {function(number)} callback + * @param {Object} context + * @param {number} tickTime + * @param {number} startTicks + */ + var TimelineEvent = function(callback, context, tickTime, startTicks){ + this.startTicks = startTicks; + this.tickTime = tickTime; + this.callback = callback; + this.context = context; + this.id = TimelineEventIDCounter++; + }; + + /** + * invoke the callback in the correct context + * passes in the playback time + * + * @param {number} playbackTime + */ + TimelineEvent.prototype.doCallback = function(playbackTime){ + this.callback.call(this.context, playbackTime); + }; + + /** + * get the tick which the callback is supposed to occur on + * + * @return {number} + */ + TimelineEvent.prototype.callbackTick = function(){ + return this.startTicks + this.tickTime; + }; + + /** + * test if the tick occurs on the interval + * + * @param {number} tick + * @return {boolean} + */ + TimelineEvent.prototype.testInterval = function(tick){ + return (tick - this.startTicks) % this.tickTime === 0; + }; + + + /////////////////////////////////////////////////////////////////////////////// + // AUGMENT TONE'S PROTOTYPE TO INCLUDE TRANSPORT TIMING + /////////////////////////////////////////////////////////////////////////////// + + /** + * tests if a string is musical notation + * i.e.: + * 4n = quarter note + * 2m = two measures + * 8t = eighth-note triplet + * + * @return {boolean} + */ + Tone.prototype.isNotation = (function(){ + var notationFormat = new RegExp(/[0-9]+[mnt]$/i); + return function(note){ + return notationFormat.test(note); + }; + })(); + + /** + * tests if a string is transportTime + * i.e. : + * 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes + * + * @return {boolean} + */ + Tone.prototype.isTransportTime = (function(){ + var transportTimeFormat = new RegExp(/^\d+(\.\d+)?:\d+(\.\d+)?(:\d+(\.\d+)?)?$/); + return function(transportTime){ + return transportTimeFormat.test(transportTime); + }; + })(); + + /** + * true if the input is in the format number+hz + * i.e.: 10hz + * + * @param {number} freq + * @return {boolean} + */ + Tone.prototype.isFrequency = (function(){ + var freqFormat = new RegExp(/[0-9]+hz$/i); + return function(freq){ + return freqFormat.test(freq); + }; + })(); + + + /** + * convert notation format strings to seconds + * @param {string} notation + * @param {number=} bpm + * @param {number=} timeSignature + * @return {number} + */ + Tone.prototype.notationToSeconds = function(notation, bpm, timeSignature){ + bpm = this.defaultArg(bpm, Tone.Transport.getBpm()); + timeSignature = this.defaultArg(timeSignature, transportTimeSignature); + var beatTime = (60 / bpm); + var subdivision = parseInt(notation, 10); + var beats = 0; + if (subdivision === 0){ + beats = 0; + } + var lastLetter = notation.slice(-1); + if (lastLetter === "t"){ + beats = (4 / subdivision) * 2/3; + } else if (lastLetter === "n"){ + beats = 4 / subdivision; + } else if (lastLetter === "m"){ + beats = subdivision * timeSignature; + } else { + beats = 0; + } + return beatTime * beats; + }; + + /** + * convert transportTime into seconds + * i.e.: + * 4:2:3 == 4 measures + 2 quarters + 3 sixteenths + * + * @param {string} transportTime + * @param {number=} bpm + * @param {number=} timeSignature + * @return {number} seconds + */ + Tone.prototype.transportTimeToSeconds = function(transportTime, bpm, timeSignature){ + bpm = this.defaultArg(bpm, Tone.Transport.getBpm()); + timeSignature = this.defaultArg(timeSignature, transportTimeSignature); + var measures = 0; + var quarters = 0; + var sixteenths = 0; + var split = transportTime.split(":"); + if (split.length === 2){ + measures = parseFloat(split[0]); + quarters = parseFloat(split[1]); + } else if (split.length === 1){ + quarters = parseFloat(split[0]); + } else if (split.length === 3){ + measures = parseFloat(split[0]); + quarters = parseFloat(split[1]); + sixteenths = parseFloat(split[2]); + } + var beats = (measures * timeSignature + quarters + sixteenths / 4); + return beats * this.notationToSeconds("4n"); + }; + + /** + * Convert seconds to the closest transportTime in the form + * measures:quarters:sixteenths + * + * @param {Tone.Time} seconds + * @param {number=} bpm + * @param {number=} timeSignature + * @return {string} + */ + Tone.prototype.toTransportTime = function(time, bpm, timeSignature){ + var seconds = this.toSeconds(time, bpm, timeSignature); + bpm = this.defaultArg(bpm, Tone.Transport.getBpm()); + timeSignature = this.defaultArg(timeSignature, transportTimeSignature); + var quarterTime = this.notationToSeconds("4n"); + var quarters = seconds / quarterTime; + var measures = Math.floor(quarters / timeSignature); + var sixteenths = Math.floor((quarters % 1) * 4); + quarters = Math.floor(quarters) % timeSignature; + var progress = [measures, quarters, sixteenths]; + return progress.join(":"); + }; + + /** + * convert a time to a frequency + * + * @param {Tone.Time} time + * @return {number} the time in hertz + */ + Tone.prototype.toFrequency = function(time, bpm, timeSignature){ + if (this.isFrequency(time)){ + return parseFloat(time); + } else if (this.isNotation(time) || this.isTransportTime(time)) { + return this.secondsToFrequency(this.toSeconds(time, bpm, timeSignature)); + } else { + return time; + } + }; + + /** + * convert Tone.Time into seconds + * + * unlike the method which it overrides, this takes into account + * transporttime and musical notation + * + * @param {Tone.Time} time + * @param {number=} bpm + * @param {number=} timeSignature + */ + Tone.prototype.toSeconds = function(time, bpm, timeSignature){ + if (typeof time === "number"){ + return time; //assuming that it's seconds + } else if (typeof time === "string"){ + var plusTime = 0; + if(time.charAt(0) === "+") { + plusTime = this.now(); + time = time.slice(1); + } + if (this.isNotation(time)){ + time = this.notationToSeconds(time, bpm, timeSignature); + } else if (this.isTransportTime(time)){ + time = this.transportTimeToSeconds(time, bpm, timeSignature); + } else if (this.isFrequency(time)){ + time = this.frequencyToSeconds(time, bpm, timeSignature); + } else { + time = parseFloat(time); + } + return time + plusTime; + } else { + return this.now(); + } + }; + + //a single transport object + Tone.Transport = new Tone.Transport(); + + return Tone.Transport; +}); + +define('Tone/source/Source',["Tone/core/Tone"], +function(Tone){ + + /** + * base class for sources + * + * @constructor + * @extends {Tone} + */ + Tone.Source = function(){ + /** + * unlike most ToneNodes, Sources only have an output and no input + * + * @type {GainNode} + */ + this.output = this.context.createGain(); + }; + + Tone.extend(Tone.Source); + + /** + * @abstract + * @param {Tone.Time} time + */ + Tone.Source.prototype.start = function(){}; + + /** + * @abstract + * @param {Tone.Time} time + */ + Tone.Source.prototype.stop = function(){}; + + /** + * @abstract + * @param {Tone.Time} time + */ + Tone.Source.prototype.pause = function(){}; + + /** + * @param {number} value + * @param {Tone.Time} time (relative to 'now') + */ + Tone.Source.prototype.fadeTo = function(value, time){ + var currentVolume = this.output.gain.value; + var now = this.now(); + this.output.gain.cancelScheduledValues(now); + this.output.gain.setValueAtTime(currentVolume, now); + this.output.gain.linearRampToValueAtTime(value, this.toSeconds(time)); + }; + + /** + * @param {number} value + */ + Tone.Source.prototype.setVolume = function(value){ + this.output.gain.value = value; + }; + + return Tone.Source; +}); +define('Tone/source/Oscillator',["Tone/core/Tone", "Tone/core/Transport", "Tone/signal/Signal", "Tone/source/Source"], +function(Tone){ + + /** + * Oscillator + * + * Oscilator with start, pause, stop and sync to Transport + * + * @constructor + * @extends {Tone.Source} + * @param {number|string=} freq starting frequency + * @param {string=} type type of oscillator (sine|square|triangle|sawtooth) + */ + Tone.Oscillator = function(freq, type){ + Tone.Source.call(this); + + /** + * the main oscillator + * @type {OscillatorNode} + */ + this.oscillator = this.context.createOscillator(); + /** + * the frequency control signal + * @type {Tone.Signal} + */ + this.frequency = new Tone.Signal(this.defaultArg(this.toFrequency(freq), 440)); + + //connections + this.oscillator.connect(this.output); + //setup + this.oscillator.type = this.defaultArg(type, "sine"); + }; + + Tone.extend(Tone.Oscillator, Tone.Source); + + /** + * start the oscillator + * + * @param {Tone.Time} time + */ + Tone.Oscillator.prototype.start = function(time){ + //get previous values + var type = this.oscillator.type; + var detune = this.oscillator.frequency.value; + //new oscillator with previous values + this.oscillator = this.context.createOscillator(); + this.oscillator.type = type; + this.oscillator.detune.value = detune; + //connect the control signal to the oscillator frequency + this.oscillator.connect(this.output); + this.frequency.connect(this.oscillator.frequency); + this.oscillator.frequency.value = 0; + //start the oscillator + this.oscillator.start(this.toSeconds(time)); + }; + + /** + * Sync the oscillator to the transport + * + * the current ratio between the oscillator and the Transport BPM + * is fixed and any change to the Transport BPM will change this + * oscillator in that same ratio + * + * Transport start/pause/stop will also start/pause/stop the oscillator + */ + Tone.Oscillator.prototype.sync = function(){ + Tone.Transport.sync(this, this.frequency); + }; + + /** + * unsync the oscillator from the Transport + */ + Tone.Oscillator.prototype.unsync = function(){ + Tone.Transport.unsync(this); + this.frequency.unsync(); + }; + + /** + * stop the oscillator + * @param {Tone.Time=} time (optional) timing parameter + */ + Tone.Oscillator.prototype.stop = function(time){ + this.oscillator.stop(this.toSeconds(time)); + }; + + /** + * exponentially ramp the frequency of the oscillator over the rampTime + * + * @param {Tone.Time} val + * @param {Tone.Time=} rampTime when the oscillator will arrive at the frequency + */ + Tone.Oscillator.prototype.setFrequency = function(val, rampTime){ + this.frequency.exponentialRampToValueAtTime(this.toFrequency(val), this.toSeconds(rampTime)); + }; + + /** + * set the oscillator type + * + * @param {string} type (sine|square|triangle|sawtooth) + */ + Tone.Oscillator.prototype.setType = function(type){ + this.oscillator.type = type; + }; + + return Tone.Oscillator; +}); +define('Tone/component/LFO',["Tone/core/Tone", "Tone/source/Oscillator", "Tone/signal/Scale"], function(Tone){ + + /** + * Low Frequency Oscillator + * + * LFO produces an output signal which can be attached to an AudioParam + * for constant control over that parameter + * the LFO can also be synced to the transport + * + * @constructor + * @extends {Tone} + * @param {number} rate + * @param {number=} outputMin + * @param {number=} outputMax + */ + Tone.LFO = function(rate, outputMin, outputMax){ + + Tone.call(this); + + /** @type {Tone.Oscillator} */ + this.oscillator = new Tone.Oscillator(rate, "sine"); + /** @type {Tone.Scale} */ + this.scaler = new Tone.Scale(this.defaultArg(outputMin, 0), this.defaultArg(outputMax, 1)); + + //connect it up + this.chain(this.oscillator, this.scaler, this.output); + }; + + Tone.extend(Tone.LFO); + + + /** + * start the LFO + * @param {Tone.Time} time + */ + Tone.LFO.prototype.start = function(time){ + this.oscillator.start(time); + }; + + /** + * stop the LFO + * @param {Tone.Time} time + */ + Tone.LFO.prototype.stop = function(time){ + this.oscillator.stop(time); + }; + + /** + * Sync the start/stop/pause to the transport + * and the frequency to the bpm of the transport + */ + Tone.LFO.prototype.sync = function(){ + this.oscillator.sync(); + }; + + /** + * unsync the LFO from transport control + */ + Tone.LFO.prototype.unsync = function(){ + this.oscillator.unsync(); + }; + + + /** + * set the frequency + * @param {number} rate + */ + Tone.LFO.prototype.setFrequency = function(rate){ + this.oscillator.setFrequency(rate); + }; + + /** + * set the minimum output of the LFO + * @param {number} min + */ + Tone.LFO.prototype.setMin = function(min){ + this.scaler.setOutputMin(min); + }; + + /** + * set the maximum output of the LFO + * @param {number} min + */ + Tone.LFO.prototype.setMax = function(max){ + this.scaler.setOuputMax(max); + }; + + /** + * set the waveform of the LFO + * @param {string} type + */ + Tone.LFO.prototype.setType = function(type){ + this.oscillator.setType(type); + }; + + /** + * pointer to the parent's connect method + * @private + */ + Tone.LFO.prototype._connect = Tone.prototype.connect; + + /** + * override the connect method so that it 0's out the value + * if attached to an AudioParam + * + * @override + * @param {AudioNode|AudioParam|Tone} param + */ + Tone.LFO.prototype.connect = function(param){ + if (param instanceof AudioParam){ + //set the initial value + param.value = 0; + } + this._connect(param); + }; + + return Tone.LFO; +}); +define('Tone/component/Meter',["Tone/core/Tone", "Tone/core/Master"], function(Tone){ + + /** + * get the rms of the input signal with some averaging + * can also just get the value of the signal + * or the value in dB + * + * inspired by https://github.com/cwilso/volume-meter/blob/master/volume-meter.js + * The MIT License (MIT) Copyright (c) 2014 Chris Wilson + * + * @constructor + * @extends {Tone} + * @param {number=} channels (optional) number of channels being metered + * @param {number=} smoothing (optional) amount of smoothing applied to the volume + * @param {number=} clipMemory (optional) number in ms that a "clip" should be remembered + */ + Tone.Meter = function(channels, smoothing, clipMemory){ + //extends Unit + Tone.call(this); + + /** @type {number} */ + this.channels = this.defaultArg(channels, 1); + + /** @type {number} */ + this.smoothing = this.defaultArg(smoothing, 0.8); + + /** @type {number} */ + this.clipMemory = this.defaultArg(clipMemory, 500); + + /** + * the rms for each of the channels + * @private + * @type {Array} + */ + this._volume = new Array(this.channels); + + /** + * the raw values for each of the channels + * @private + * @type {Array} + */ + this._values = new Array(this.channels); + + //zero out the volume array + for (var i = 0; i < this.channels; i++){ + this._volume[i] = 0; + this._values[i] = 0; + } + + /** + * last time the values clipped + * @private + * @type {number} + */ + this._lastClip = 0; + + /** + * @private + * @type {ScriptProcessorNode} + */ + this._jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, 1); + this._jsNode.onaudioprocess = this._onprocess.bind(this); + //so it doesn't get garbage collected + this._jsNode.toMaster(); + + //signal just passes + this.input.connect(this.output); + this.input.connect(this._jsNode); + }; + + Tone.extend(Tone.Meter); + + /** + * called on each processing frame + * @private + * @param {AudioProcessingEvent} event + */ + Tone.Meter.prototype._onprocess = function(event){ + var bufferSize = this._jsNode.bufferSize; + var smoothing = this.smoothing; + for (var channel = 0; channel < this.channels; channel++){ + var input = event.inputBuffer.getChannelData(channel); + var sum = 0; + var total = 0; + var x; + var clipped = false; + for (var i = 0; i < bufferSize; i++){ + x = input[i]; + if (!clipped && x > 0.95){ + clipped = true; + this._lastClip = Date.now(); + } + total += x; + sum += x * x; + } + var average = total / bufferSize; + var rms = Math.sqrt(sum / bufferSize); + this._volume[channel] = Math.max(rms, this._volume[channel] * smoothing); + this._values[channel] = average; + } + }; + + /** + * get the rms of the signal + * + * @param {number=} channel which channel + * @return {number} the value + */ + Tone.Meter.prototype.getLevel = function(channel){ + channel = this.defaultArg(channel, 0); + var vol = this._volume[channel]; + if (vol < 0.00001){ + return 0; + } else { + return vol; + } + }; + + /** + * get the value of the signal + * @param {number=} channel + * @return {number} + */ + Tone.Meter.prototype.getValue = function(channel){ + channel = this.defaultArg(channel, 0); + return this._values[channel]; + }; + + /** + * get the volume of the signal in dB + * @param {number=} channel + * @return {number} + */ + Tone.Meter.prototype.getDb = function(channel){ + return this.gainToDb(this.getLevel(channel)); + }; + + // @returns {boolean} if the audio has clipped in the last 500ms + Tone.Meter.prototype.isClipped = function(){ + return Date.now() - this._lastClip < this.clipMemory; + }; + + return Tone.Meter; +}); +define('Tone/signal/Merge',["Tone/core/Tone"], function(Tone){ + + /** + * merge a left and a right channel into a single stereo channel + * + * instead of connecting to the input, connect to either the left, or right input + * + * default input for connect is left input + * + * @constructor + * @extends {Tone} + */ + Tone.Merge = function(){ + + Tone.call(this); + + /** + * the left input channel + * also an alias for the input + * @type {GainNode} + */ + this.left = this.input; + /** + * the right input channel + * @type {GainNode} + */ + this.right = this.context.createGain(); + /** + * the merger node for the two channels + * @type {ChannelMergerNode} + */ + this.merger = this.context.createChannelMerger(2); + + //connections + this.left.connect(this.merger, 0, 0); + this.right.connect(this.merger, 0, 1); + this.merger.connect(this.output); + }; + + Tone.extend(Tone.Merge); + + return Tone.Merge; +}); + +/////////////////////////////////////////////////////////////////////////////// +// +// PANNER +// +// Equal Power Gain L/R Panner. Not 3D +// 0 = 100% Left +// 1 = 100% Right +/////////////////////////////////////////////////////////////////////////////// + +define('Tone/component/Panner',["Tone/core/Tone", "Tone/signal/Merge", "Tone/signal/Signal", "Tone/signal/Scale"], +function(Tone){ + + Tone.Panner = function(){ + Tone.call(this); + + //components + //incoming signal is sent to left and right + this.left = this.context.createGain(); + this.right = this.context.createGain(); + this.control = new Tone.Signal(); + this.merge = new Tone.Merge(); + this.invert = new Tone.Scale(1, 0); + this.normal = new Tone.Scale(0, 1); + + //connections + this.chain(this.input, this.left, this.merge.left); + this.chain(this.input, this.right, this.merge.right); + this.merge.connect(this.output); + //left channel control + this.chain(this.control, this.invert, this.left.gain); + //right channel control + this.chain(this.control, this.normal, this.right.gain); + + + //setup + this.left.gain.value = 0; + this.right.gain.value = 0; + this.setPan(.5); + } + + Tone.extend(Tone.Panner); + + Tone.Panner.prototype.setPan = function(val, rampTime){ + rampTime = this.defaultArg(rampTime, 0); + //put val into -1 to 1 range + this.control.linearRampToValueAtTime(val * 2 - 1, rampTime); + } + + return Tone.Panner; +});; +define('Tone/component/Recorder',["Tone/core/Tone", "Tone/core/Master"], function(Tone){ + + /** + * Record an input into an array or AudioBuffer + * + * it is limited in that the recording length needs to be known beforehand + * + * @constructor + * @extends {Tone} + * @param {number} channels + */ + Tone.Recorder = function(channels){ + + Tone.call(this); + + /** + * the number of channels in the recording + * @type {number} + */ + this.channels = this.defaultArg(channels, 1); + + /** + * @private + * @type {ScriptProcessorNode} + */ + this._jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, 1); + this._jsNode.onaudioprocess = this._audioprocess.bind(this); + + /** + * Float32Array for each channel + * @private + * @type {Array} + */ + this._recordBuffers = new Array(this.channels); + + /** + * @private + * @type {number} + */ + this._recordBufferOffset = 0; + + //connect it up + this.input.connect(this._jsNode); + //pass thru audio + this.input.connect(this.output); + //so it doesn't get garbage collected + this._jsNode.toMaster(); + //clear it to start + this.clear(); + }; + + Tone.extend(Tone.Recorder); + + /** + * internal method called on audio process + * + * @private + * @param {AudioProcessorEvent} event + */ + Tone.Recorder.prototype._audioprocess = function(event){ + if (this._recordBuffers[0] === null || this._recordBuffers[0].length - this._recordBufferOffset === 0){ + return; + } + var input = event.inputBuffer; + var totalWrittenToBuffer = 0; + var recordBufferLength = this._recordBuffers[0].length; + for (var channelNum = 0; channelNum < input.numberOfChannels; channelNum++){ + var bufferOffset = this._recordBufferOffset; + var channel = input.getChannelData(channelNum); + var bufferLen = channel.length; + if (recordBufferLength - bufferOffset > bufferLen){ + this._recordBuffers[channelNum].set(channel, bufferOffset); + totalWrittenToBuffer += bufferLen; + } else { + for (var i = 0; i < bufferLen; i++) { + if (recordBufferLength > bufferOffset){ + this._recordBuffers[channelNum][bufferOffset] = channel[i]; + bufferOffset++; + totalWrittenToBuffer++; + } else { + break; + } + } + } + } + this._recordBufferOffset += totalWrittenToBuffer / input.numberOfChannels; + }; + + /** + * Record for a certain period of time + * + * will clear the internal buffer before starting + * + * @param {Tone.Time} time + */ + Tone.Recorder.prototype.record = function(time){ + this.clear(); + var recordBufferLength = this.toSamples(time); + for (var i = 0; i < this.channels; i++){ + this._recordBuffers[i] = new Float32Array(recordBufferLength); + } + }; + + /** + * clears the recording buffer + */ + Tone.Recorder.prototype.clear = function(){ + for (var i = 0; i < this.channels; i++){ + this._recordBuffers[i] = null; + } + this._recordBufferOffset = 0; + }; + + + /** + * true if there is nothing in the buffers + * @return {boolean} + */ + Tone.Recorder.prototype.isEmpty = function(){ + return this._recordBuffers[0] === null; + }; + + /** + * @return {Array} + */ + Tone.Recorder.prototype.getFloat32Array = function(){ + if (this.isEmpty()){ + return null; + } else { + return this._recordBuffers; + } + }; + + /** + * @return {AudioBuffer} + */ + Tone.Recorder.prototype.getAudioBuffer = function(){ + if (this.isEmpty()){ + return null; + } else { + var audioBuffer = this.context.createBuffer(this.channels, this._recordBuffers[0].length, this.context.sampleRate); + for (var channelNum = 0; channelNum < audioBuffer.numberOfChannels; channelNum++){ + var channel = audioBuffer.getChannelData(channelNum); + channel.set(this._recordBuffers[channelNum]); + } + return audioBuffer; + } + }; + + + return Tone.Recorder; +}); +define('Tone/core/Bus',["Tone/core/Tone"], function(Tone){ + + /** + * @fileOverview + * + * buses are another way of routing audio + * + * augments Tone.prototype to include send and recieve + */ + + /** + * All of the routes + * + * @type {Object} + */ + var Buses = {}; + + /** + * send signal to a channel name + * + * @param {string} channelName + * @param {number} amount + * @return {GainNode} + */ + Tone.prototype.send = function(channelName, amount){ + if (!Buses.hasOwnProperty(channelName)){ + Buses[channelName] = this.context.createGain(); + } + var sendKnob = this.context.createGain(); + sendKnob.gain.value = this.defaultArg(amount, 1); + this.chain(this.output, sendKnob, Buses[channelName]); + return sendKnob; + }; + + /** + * recieve the input from the desired channelName to the input gain of 'this' node. + * + * @param {string} channelName + */ + Tone.prototype.receive = function(channelName){ + if (!Buses.hasOwnProperty(channelName)){ + Buses[channelName] = this.context.createGain(); + } + Buses[channelName].connect(this.input); + }; + + // Tone.Buses = Buses; + + // return Buses; +}); +/////////////////////////////////////////////////////////////////////////////// +// +// EFFECTS UNIT +// +// connect the effect to the effectSend and to the effectReturn +// setDry(-1) = 100% Wet +// setDry(1) = 100% Dry +/////////////////////////////////////////////////////////////////////////////// + +define('Tone/effects/Effect',["Tone/core/Tone", "Tone/component/DryWet"], function(Tone){ + + Tone.Effect = function(){ + //extends Unit + Tone.call(this); + + //components + this.dryWet = new Tone.DryWet(); + this.effectSend = this.context.createGain(); + this.effectReturn = this.context.createGain(); + + //connections + this.input.connect(this.dryWet.dry); + this.input.connect(this.effectSend); + this.effectReturn.connect(this.dryWet.wet); + this.dryWet.connect(this.output); + + //setup + this.setDry(0); + } + + Tone.extend(Tone.Effect, Tone); + + //adjust the dry/wet balance + //dryness -1 to 1 + // 1 = 100% dry + //-1 = 100% wet + //@param {number} dryness + //@param {number=} rampTime + Tone.Effect.prototype.setDry = function(dryness, rampTime){ + this.dryWet.setDry(dryness, rampTime) + } + + //@param {number} dryness + //@param {number=} rampTime + Tone.Effect.prototype.setWet = function(wetVal, rampTime){ + this.setDry(-wetVal, rampTime); + } + + Tone.Effect.prototype.bypass = function(){ + this.setDry(1, 0); + } + + Tone.Effect.prototype.connectEffect = function(effect){ + this.chain(this.effectSend, effect, this.effectReturn); + } + + return Tone.Effect; +}); +define('Tone/effects/AutoPanner',["Tone/core/Tone", "Tone/source/Oscillator", "Tone/component/Panner", "Tone/effects/Effect"], function(Tone){ + + /** + * AutoPanner creates a left-right panner effect (not a 3D panner). + * + * @constructor + * @param { number= } rate (optional) rate in HZ of the left-right pan + * @param { number= } amount (optional) of the pan in dB (0 - 1) + */ + Tone.AutoPanner = function(rate, amount){ + Tone.Effect.call(this); + + //defaults + amount = this.defaultArg(amount, 1); + rate = this.defaultArg(rate, 1); + + //components + this.osc = new Tone.Oscillator(rate); + this.amount = this.context.createGain(); + this.panner = new Tone.Panner(); + + //connections + this.connectEffect(this.panner); + this.chain(this.osc, this.amount, this.panner.control); + }; + + //extend Effect + Tone.extend(Tone.AutoPanner, Tone.Effect); + + /** + * Start the panner + * + * @param {Tone.Time} Time the panner begins. + */ + Tone.AutoPanner.prototype.start = function(time){ + this.osc.start(time); + }; + + /** + * Stop the panner + * + * @param {Tone.Time} time the panner stops. + */ + Tone.AutoPanner.prototype.stop = function(time){ + this.osc.stop(time); + }; + + /** + * Set the type of oscillator attached to the AutoPanner. + * + * @param {string} type of oscillator the panner is attached to (sine|sawtooth|triangle|square) + */ + Tone.AutoPanner.prototype.setType = function(type){ + this.osc.setType(type); + }; + + /** + * Set frequency of the oscillator attached to the AutoPanner. + * + * @param {number|string} rate in HZ of the oscillator's frequency. + */ + Tone.AutoPanner.prototype.setFrequency = function(rate){ + this.osc.setFrequency(rate); + }; + + /** + * Set the amount of the AutoPanner. + * + * @param {number} amount in dB (0 - 1) + */ + Tone.AutoPanner.prototype.setAmount = function(amount){ + this.amount.gain.value = amount; + }; + + return Tone.AutoPanner; +}); + +/////////////////////////////////////////////////////////////////////////////// +// +// FEEDBACK EFFECTS +// +// an effect with feedback +/////////////////////////////////////////////////////////////////////////////// + +define('Tone/effects/FeedbackEffect',["Tone/core/Tone", "Tone/effects/Effect"], function(Tone){ + + Tone.FeedbackEffect = function(){ + //extends Unit + Tone.Effect.call(this); + + this.feedback = this.context.createGain(); + //feedback loop + this.chain(this.effectReturn, this.feedback, this.effectSend); + + //some initial values + this.setFeedback(0); + } + + Tone.extend(Tone.FeedbackEffect, Tone.Effect); + + Tone.FeedbackEffect.prototype.setFeedback = function(fback){ + this.rampToValueNow(this.feedback.gain, fback); + } + + return Tone.FeedbackEffect; +}); + +/////////////////////////////////////////////////////////////////////////////// +// +// FEEDBACK DELAY +// +/////////////////////////////////////////////////////////////////////////////// + +define('Tone/effects/FeedbackDelay',["Tone/core/Tone", "Tone/effects/FeedbackEffect"], function(Tone){ + + //@param {number} delayTime + Tone.FeedbackDelay = function(delayTime){ + Tone.FeedbackEffect.call(this); + + this.delay = this.context.createDelay(4); + this.delay.delayTime.value = this.toSeconds(this.defaultArg(delayTime, .25)); + + //connect it up + this.connectEffect(this.delay); + } + + Tone.extend(Tone.FeedbackDelay, Tone.FeedbackEffect); + + Tone.FeedbackDelay.prototype.setDelayTime = function(delayTime){ + this.rampToValueNow(this.delay.delayTime, this.toSeconds(delayTime)); + } + + return Tone.FeedbackDelay; +}); +/////////////////////////////////////////////////////////////////////////////// +// +// PING PONG DELAY +// +/////////////////////////////////////////////////////////////////////////////// + +define('Tone/effects/PingPongDelay',["Tone/core/Tone", "Tone/effects/FeedbackDelay"], function(Tone){ + + + //@param {number=} delayTime + Tone.PingPongDelay = function(delayTime){ + Tone.StereoSplit.call(this); + + //components + this.leftDelay = new Tone.FeedbackDelay(delayTime); + this.rightDelay = new Tone.FeedbackDelay(delayTime); + + + //connect it up + this.connectLeft(this.leftDelay); + this.connectRight(this.rightDelay); + + //disconnect the feedback lines to connect them to the other delay + // http://jvzaudio.files.wordpress.com/2011/04/delay-f43.gif + this.leftDelay.feedback.disconnect(); + this.rightDelay.feedback.disconnect(); + this.leftDelay.feedback.connect(this.rightDelay.effectSend); + this.rightDelay.feedback.connect(this.leftDelay.effectSend); + + //initial vals; + this.setDelayTime(delayTime); + } + + Tone.extend(Tone.PingPongDelay, Tone.StereoSplit); + + //@param {number} delayTime + Tone.PingPongDelay.prototype.setDelayTime = function(delayTime){ + this.leftDelay.setDelayTime(delayTime); + this.rightDelay.setDelayTime(delayTime * 2); + } + + //@param {number} feedback (0 - 1) + Tone.PingPongDelay.prototype.setFeedback = function(feedback){ + this.leftDelay.setFeedback(feedback); + this.rightDelay.setFeedback(feedback); + } + + //@param {number} wet (0 - 1) + Tone.PingPongDelay.prototype.setWet = function(wet){ + this.leftDelay.setWet(wet); + this.rightDelay.setWet(wet); + } + + //@param {number} dry (0 - 1) + Tone.PingPongDelay.prototype.setDry = function(dry){ + this.leftDelay.setDry(dry); + this.rightDelay.setDry(dry); + } + + return Tone.PingPongDelay; +}); + +define('Tone/instrument/MonoSynth',["Tone/core/Tone", "Tone/component/Envelope", "Tone/source/Oscillator"], function(Tone){ + + + Tone.MonoSynth = function(){ + //one oscillator + this.oscillator = this.context.createOscillator(); + this.glideTime = .01; + this.filterEnvelope = new Tone.Envelope(); + } + + return Tone.MonoSynth; +}); +/////////////////////////////////////////////////////////////////////////////// +// +// AUDIO PLAYER +// +/////////////////////////////////////////////////////////////////////////////// + +define('Tone/source/Player',["Tone/core/Tone"], function(Tone){ + + Tone.Player = function(url){ + //extend Unit + Tone.call(this); + + //player vars + this.url = url; + this.source = null; + this.buffer = null; + + this.onended = function(){}; + } + + Tone.extend(Tone.Player, Tone); + + //makes an xhr for the buffer at the url + //invokes the callback at the end + //@param {function(Tone.Player)} callback + Tone.Player.prototype.load = function(callback){ + if (!this.buffer){ + var request = new XMLHttpRequest(); + request.open('GET', this.url, true); + request.responseType = 'arraybuffer'; + // decode asynchronously + var self = this; + request.onload = function() { + self.context.decodeAudioData(request.response, function(buff) { + self.buffer = buff; + if (callback){ + callback(self); + } + }); + } + //send the request + request.send(); + } else { + if (callback){ + callback(this); + } + } + } + + //play the buffer from start to finish at a time + Tone.Player.prototype.start = function(startTime, offset, duration, volume){ + if (this.buffer){ + //default args + startTime = this.defaultArg(startTime, this.now()); + offset = this.defaultArg(offset, 0); + duration = this.defaultArg(duration, this.buffer.duration - offset); + volume = this.defaultArg(volume, 1); + //make the source + this.source = this.context.createBufferSource(); + this.source.buffer = this.buffer; + this.source.loop = false; + this.source.start(this.toSeconds(startTime), this.toSeconds(offset), this.toSeconds(duration)); + this.source.onended = this._onended.bind(this); + var gain = this.context.createGain(); + gain.gain.value = volume; + this.chain(this.source, gain, this.output); + } + } + + //play the buffer from start to finish at a time + Tone.Player.prototype.loop = function(startTime, loopStart, loopEnd, offset, duration, volume){ + if (this.buffer){ + //default args + startTime = this.defaultArg(startTime, this.now()); + loopStart = this.defaultArg(loopStart, 0); + loopEnd = this.defaultArg(loopEnd, this.buffer.duration); + offset = this.defaultArg(offset, loopStart); + duration = this.defaultArg(duration, this.buffer.duration - offset); + //make/play the source + this.start(startTime, offset, duration, volume); + this.source.loop = true; + this.source.loopStart = this.toSeconds(loopStart); + this.source.loopEnd = this.toSeconds(loopEnd); + } + } + + //stop playback + Tone.Player.prototype.stop = function(stopTime){ + if (this.buffer && this.source){ + stopTime = this.defaultArg(stopTime, this.now()); + this.source.stop(this.toSeconds(stopTime)); + } + } + + //@returns {number} the buffer duration + Tone.Player.prototype.getDuration = function(){ + if (this.buffer){ + this.buffer.duration; + } else { + return 0; + } + } + + //@param {function(Event)} callback + Tone.Player.prototype._onended = function(e){ + this.onended(e); + } + + return Tone.Player; +}); + +/////////////////////////////////////////////////////////////////////////////// +// +// SAMPLE PLAYER +// +// dependencies : Tone, Player, Envelope, LFO +/////////////////////////////////////////////////////////////////////////////// + +define('Tone/instrument/Sampler',["Tone/core/Tone", "Tone/component/Envelope", "Tone/source/Player"], function(Tone){ + + Tone.Sampler = function(url){ + Tone.call(this); + + //components + this.player = new Tone.Player(url); + this.envelope = new Tone.Envelope(.1, .01, .1, 1); + this.filter = this.context.createBiquadFilter(); + this.filter.type = "lowpass"; + this.filter.Q.value = 12; + this.filterEnvelope = new Tone.Envelope(.4, 0, 1, .6, this.filter.frequency, 0, 1200); + + //connect it up + this.chain(this.player, this.envelope, this.filter, this.output); + } + + Tone.extend(Tone.Sampler, Tone); + + + //@param {function()=} callback + Tone.Sampler.prototype.load = function(callback){ + this.player.load(callback); + } + + Tone.Sampler.prototype.triggerAttack = function(startTime){ + this.player.start(startTime); + this.envelope.triggerAttack(startTime); + this.filterEnvelope.triggerAttack(startTime); + } + + Tone.Sampler.prototype.triggerRelease = function(stopTime){ + stopTime = this.defaultArg(stopTime, this.now()); + this.player.stop(stopTime + Math.max(this.envelope.release, this.filterEnvelope.release)); + this.envelope.triggerRelease(stopTime); + this.filterEnvelope.triggerRelease(stopTime); + } + + return Tone.Sampler; +}); +define('Tone/signal/BitCrusher',["Tone/core/Tone"], function(Tone){ + + /** + * downsample incoming signal + * inspiration from https://github.com/jaz303/bitcrusher/blob/master/index.js + * + * @constructor + * @extends {Tone} + * @param {number=} bits + * @param {number=} frequency + */ + Tone.BitCrusher = function(bits, frequency){ + + Tone.call(this); + + /** + * @private + * @type {number} + */ + this._bits = this.defaultArg(bits, 8); + + /** + * @private + * @type {number} + */ + this._frequency = this.defaultArg(frequency, 0.5); + + /** + * @private + * @type {number} + */ + this._step = 2 * Math.pow(0.5, this._bits); + + /** + * @private + * @type {number} + */ + this._invStep = 1/this._step; + + /** + * @private + * @type {number} + */ + this._phasor = 0; + + /** + * @private + * @type {number} + */ + this._last = 0; + + /** + * @private + * @type {ScriptProcessorNode} + */ + this._crusher = this.context.createScriptProcessor(this.bufferSize, 1, 1); + this._crusher.onaudioprocess = this._audioprocess.bind(this); + + //connect it up + this.chain(this.input, this._crusher, this.output); + }; + + Tone.extend(Tone.BitCrusher); + + /** + * @private + * @param {AudioProcessingEvent} event + */ + Tone.BitCrusher.prototype._audioprocess = function(event){ + //cache the values used in the loop + var phasor = this._phasor; + var freq = this._frequency; + var invStep = this._invStep; + var last = this._last; + var step = this._step; + var input = event.inputBuffer.getChannelData(0); + var output = event.outputBuffer.getChannelData(0); + for (var i = 0, len = output.length; i < len; i++) { + phasor += freq; + if (phasor >= 1) { + phasor -= 1; + last = step * ((input[i] * invStep) | 0 + 0.5); + } + output[i] = last; + } + //set the values for the next loop + this._phasor = phasor; + this._last = last; + }; + + /** + * set the bit rate + * + * @param {number} bits + */ + Tone.BitCrusher.prototype.setBits = function(bits){ + this._bits = bits; + this._step = 2 * Math.pow(0.5, this._bits); + this._invStep = 1/this._step; + }; + + /** + * set the frequency + * @param {number} freq + */ + Tone.BitCrusher.prototype.setFrequency = function(freq){ + this._frequency = freq; + }; + + return Tone.BitCrusher; +}); +define('Tone/signal/Split',["Tone/core/Tone"], function(Tone){ + + /** + * split the incoming signal into left and right channels + * + * the left channel is the default output + * + * @constructor + * @extends {Tone} + */ + Tone.Split = function(){ + Tone.call(this); + + /** @type {ChannelSplitterNode} */ + this.splitter = this.context.createChannelSplitter(2); + /** + * left channel output + * @alias for the default output + * @type {GainNode} + */ + this.left = this.output; + /** + * the right channel output + * @type {GainNode} + */ + this.right = this.context.createGain(); + + //connections + this.input.connect(this.splitter); + this.splitter.connect(this.left, 1, 0); + this.splitter.connect(this.right, 0, 0); + }; + + Tone.extend(Tone.Split); + + return Tone.Split; +}); +/////////////////////////////////////////////////////////////////////////////// +// +// WEB RTC MICROPHONE +// +/////////////////////////////////////////////////////////////////////////////// + +define('Tone/source/Microphone',["Tone/core/Tone"], function(Tone){ + + //@param {number=} inputNum + Tone.Microphone = function(inputNum){ + //extend the base class + Tone.call(this); + + //components + this.mediaStream = null; + this.stream = null; + this.constraints = {"audio" : true}; + //get that option + var self = this; + MediaStreamTrack.getSources(function (media_sources) { + if (inputNum < media_sources.length){ + self.constraints.audio = { + optional : [{ sourceId: media_sources[inputNum].id}] + } + } + }); + } + + Tone.extend(Tone.Microphone, Tone); + + //stop the WebRTC connection + Tone.Microphone.prototype.start = function(){ + // Only get the audio stream. + navigator.getUserMedia(this.constraints, this._onStream.bind(this), this._onStreamError.bind(this)); + } + + //stop the WebRTC connection + Tone.Microphone.prototype.stop = function(){ + if (this.stream){ + this.stream.stop(); + } + } + + //when the stream is setup + Tone.Microphone.prototype._onStream = function(stream) { + this.stream = stream; + // Wrap a MediaStreamSourceNode around the live input stream. + this.mediaStream = this.context.createMediaStreamSource(stream); + this.mediaStream.connect(this.output); + }; + + //on error + Tone.Microphone.prototype._onStreamError = function(e) { + console.error(e); + }; + + //polyfill + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia + || navigator.mozGetUserMedia || navigator.msGetUserMedia; + + return Tone.Microphone; +}); +/////////////////////////////////////////////////////////////////////////////// +// +// NOISE +// +/////////////////////////////////////////////////////////////////////////////// +define('Tone/source/Noise',["Tone/core/Tone"], function(Tone){ + + //@param {string} type the noise type + Tone.Noise = function(type){ + //extend Unit + Tone.call(this); + + //components + this.jsNode = this.context.createScriptProcessor(this.bufferSize, 0, 1); + + //connections + this.jsNode.connect(this.output); + + this.setType(this.defaultArg(type, "white")); + } + + Tone.extend(Tone.Noise, Tone); + + //@param {string} type ('white', 'pink', 'brown') + Tone.Noise.prototype.setType = function(type){ + switch (type){ + case "white" : + this.jsNode.onaudioprocess = this._whiteNoise.bind(this); + break; + case "pink" : + this.jsNode.onaudioprocess = this._pinkNoise.bind(this); + break; + case "brown" : + this.jsNode.onaudioprocess = this._brownNoise.bind(this); + break; + default : + this.jsNode.onaudioprocess = this._whiteNoise.bind(this); + } + } + + //modified from http://noisehack.com/generate-noise-web-audio-api/ + Tone.Noise.prototype._pinkNoise = (function() { + var b0, b1, b2, b3, b4, b5, b6; + b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0; + return function(e) { + var bufferSize = this.jsNode.bufferSize; + var output = e.outputBuffer.getChannelData(0); + for (var i = 0; i < bufferSize; 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; + output[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; + output[i] *= 0.11; // (roughly) compensate for gain + b6 = white * 0.115926; + } + } + })(); + + //modified from http://noisehack.com/generate-noise-web-audio-api/ + Tone.Noise.prototype._brownNoise = (function() { + var lastOut = 0.0; + return function(e) { + var bufferSize = this.jsNode.bufferSize; + var output = e.outputBuffer.getChannelData(0); + for (var i = 0; i < bufferSize; i++) { + var white = Math.random() * 2 - 1; + output[i] = (lastOut + (0.02 * white)) / 1.02; + lastOut = output[i]; + output[i] *= 3.5; // (roughly) compensate for gain + } + } + return node; + })(); + + //modified from http://noisehack.com/generate-noise-web-audio-api/ + Tone.Noise.prototype._whiteNoise = function(e){ + var bufferSize = this.jsNode.bufferSize; + var output = e.outputBuffer.getChannelData(0); + for (var i = 0; i < bufferSize; i++) { + output[i] = Math.random() * 2 - 1; + } + } + + return Tone.Noise; +}); \ No newline at end of file diff --git a/Tone/component/Envelope.js b/Tone/component/Envelope.js index 5da44498..07aaf550 100644 --- a/Tone/component/Envelope.js +++ b/Tone/component/Envelope.js @@ -108,8 +108,8 @@ define(["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ }; /** - * @private * pointer to the parent's connect method + * @private */ Tone.Envelope.prototype._connect = Tone.prototype.connect; diff --git a/Tone/component/LFO.js b/Tone/component/LFO.js index f95fbde5..20f638b3 100644 --- a/Tone/component/LFO.js +++ b/Tone/component/LFO.js @@ -96,7 +96,6 @@ define(["Tone/core/Tone", "Tone/source/Oscillator", "Tone/signal/Scale"], functi /** * pointer to the parent's connect method * @private - * @type {[type]} */ Tone.LFO.prototype._connect = Tone.prototype.connect; diff --git a/Tone/component/Meter.js b/Tone/component/Meter.js index 809c13f5..3576ba6c 100644 --- a/Tone/component/Meter.js +++ b/Tone/component/Meter.js @@ -28,16 +28,16 @@ define(["Tone/core/Tone", "Tone/core/Master"], function(Tone){ this.clipMemory = this.defaultArg(clipMemory, 500); /** + * the rms for each of the channels * @private * @type {Array} - * the rms for each of the channels */ this._volume = new Array(this.channels); /** + * the raw values for each of the channels * @private * @type {Array} - * the raw values for each of the channels */ this._values = new Array(this.channels); @@ -48,9 +48,9 @@ define(["Tone/core/Tone", "Tone/core/Master"], function(Tone){ } /** + * last time the values clipped * @private * @type {number} - * last time the values clipped */ this._lastClip = 0; diff --git a/Tone/core/Tone.js b/Tone/core/Tone.js index 86796098..070a5ceb 100644 --- a/Tone/core/Tone.js +++ b/Tone/core/Tone.js @@ -112,7 +112,7 @@ /** * A static pointer to the audio context - * @type {[type]} + * @type {AudioContext} */ Tone.context = audioContext; diff --git a/Tone/core/Transport.js b/Tone/core/Transport.js index 73bd5f7f..3bd9457b 100644 --- a/Tone/core/Transport.js +++ b/Tone/core/Transport.js @@ -28,27 +28,57 @@ function(Tone){ Tone.extend(Tone.Transport); - /** @private @type {number} */ + /** + * @private + * @type {number} + */ var transportTicks = 0; - /** @private @type {number} */ + /** + * @private + * @type {number} + */ var tatum = 12; - /** @private @type {boolean} */ + /** + * @private + * @type {Boolean} + */ var upTick = false; - /** @private @type {number} */ + /** + * @private + * @type {number} + */ var transportTimeSignature = 4; - /** @private @type {number} */ + /** + * @private + * @type {number} + */ var loopStart = 0; - /** @private @type {number} */ + /** + * @private + * @type {number} + */ var loopEnd = tatum * 4; - /** @private @type {Array} */ + /** + * @private + * @type {Array} + */ var intervals = []; - /** @private @type {Array} */ + /** + * @private + * @type {Array} + */ var timeouts = []; - /** @private @type {Array} */ + /** + * @private + * @type {Array} + */ var timeline = []; - /** @private @type {number} */ + /** + * @private + * @type {number} + */ var timelineProgress = 0; /** @@ -68,7 +98,8 @@ function(Tone){ /** * All of the synced components - * @private @type {Array} + * @private + * @type {Array} */ var SyncedComponents = []; @@ -508,8 +539,7 @@ function(Tone){ /** * remove the source from the list of Synced Sources * - * @param {[type]} source [description] - * @return {[type]} [description] + * @param {Tone.Source} source [description] */ Tone.Transport.prototype.unsync = function(source){ diff --git a/Tone/signal/BitCrusher.js b/Tone/signal/BitCrusher.js index ce89d79d..56c341d2 100644 --- a/Tone/signal/BitCrusher.js +++ b/Tone/signal/BitCrusher.js @@ -13,20 +13,46 @@ define(["Tone/core/Tone"], function(Tone){ Tone.call(this); - /** @private @type {number} */ + /** + * @private + * @type {number} + */ this._bits = this.defaultArg(bits, 8); - /** @private @type {number} */ + + /** + * @private + * @type {number} + */ this._frequency = this.defaultArg(frequency, 0.5); - /** @private @type {number} */ + + /** + * @private + * @type {number} + */ this._step = 2 * Math.pow(0.5, this._bits); - /** @private @type {number} */ + + /** + * @private + * @type {number} + */ this._invStep = 1/this._step; - /** @private @type {number} */ + + /** + * @private + * @type {number} + */ this._phasor = 0; - /** @private @type {number} */ + + /** + * @private + * @type {number} + */ this._last = 0; - /** @private @type {ScriptProcessorNode} */ + /** + * @private + * @type {ScriptProcessorNode} + */ this._crusher = this.context.createScriptProcessor(this.bufferSize, 1, 1); this._crusher.onaudioprocess = this._audioprocess.bind(this); diff --git a/Tone/signal/Multiply.js b/Tone/signal/Multiply.js index de78d489..f8923bf4 100644 --- a/Tone/signal/Multiply.js +++ b/Tone/signal/Multiply.js @@ -15,7 +15,7 @@ define(["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ * @type {GainNode} */ this.input = this.context.createGain(); - /** @alias */ + /** @alias {GainNode} */ this.output = this.input; //apply the inital scale factor diff --git a/build/Gruntfile.js b/build/Gruntfile.js new file mode 100644 index 00000000..51cb947d --- /dev/null +++ b/build/Gruntfile.js @@ -0,0 +1,79 @@ +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + //pkg: grunt.file.readJSON('package.json'), + jsdoc : { + src : { + src: ['../Tone/**/*.js'], + //src: ['./Tone.js'], + options: { + destination: '../doc' + } + }, + dist : { + src: ['../Tone.js'], + options: { + destination: '../doc' + } + } + }, + requirejs : { + compile: { + options: { + baseUrl: "../", + name : "main", + out: "./Tone.js.tmp", + optimize : "none" + } + } + }, + concat: { + dist: { + options: { + // Replace all 'use strict' statements in the code with a single one at the top + banner: "require([", + separator: ',', + process: function(src, filepath) { + // remove the '.js'. h@ckz0rs. + return '"' + filepath.substring(3,(filepath.length-3)) + '"'; + }, + footer: "], function(){});", + + }, + files: { + '../main.js': ['../Tone/**/*.js'], + } + }, + removeRequireString: { + options: { + process: function(src, filepath) { + // remove the '.js'. h@ckz0rs. + var withoutRequire = src.substr(0, src.indexOf("require([") - 1); + return withoutRequire; + }, + }, + files: { + '../Tone.js': ['./Tone.js.tmp'], + } + } + }, + clean: { + options: { + force: true, + }, + dist: ['../main.js','./Tone.js.tmp'] + } + }); + + // Load the plugin that provides the "uglify" task. + grunt.loadNpmTasks('grunt-jsdoc'); + grunt.loadNpmTasks('grunt-contrib-requirejs'); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-clean'); + + // Default task(s). + grunt.registerTask('src', ['jsdoc:src']); + grunt.registerTask('dist', ['concat:dist','requirejs:compile','concat:removeRequireString','clean:dist','jsdoc:dist']); + +}; \ No newline at end of file diff --git a/build/Tone.js b/build/Tone.js deleted file mode 100644 index f2904f7e..00000000 --- a/build/Tone.js +++ /dev/null @@ -1,2212 +0,0 @@ - -/////////////////////////////////////////////////////////////////////////////// -// -// TONE.js -// -// (c) Yotam Mann. 2014. -// The MIT License (MIT) -/////////////////////////////////////////////////////////////////////////////// -(function (root, factory) { - //can run with or without requirejs - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define('Tone/core/Tone',[],function () { - var Tone = factory(root); - return Tone; - }); - } else if (typeof root.Tone !== 'function') { - //make Tone public - root.Tone = factory(root); - //define 'define' to invoke the callbacks with Tone - root.define = function(name, deps, func){ - func(Tone); - } - } -} (this, function (global) { - - ////////////////////////////////////////////////////////////////////////// - // WEB AUDIO CONTEXT - /////////////////////////////////////////////////////////////////////////// - - //ALIAS - if (!global.AudioContext){ - global.AudioContext = global.webkitAudioContext; - } - - var audioContext; - if (global.AudioContext){ - audioContext = new global.AudioContext(); - } - - //SHIMS//////////////////////////////////////////////////////////////////// - - if (typeof audioContext.createGain !== "function"){ - audioContext.createGain = audioContext.createGainNode; - } - if (typeof audioContext.createDelay !== "function"){ - audioContext.createDelay = audioContext.createDelayNode; - } - if (typeof AudioBufferSourceNode.prototype.start !== "function"){ - AudioBufferSourceNode.prototype.start = AudioBufferSourceNode.prototype.noteGrainOn; - } - if (typeof AudioBufferSourceNode.prototype.stop !== "function"){ - AudioBufferSourceNode.prototype.stop = AudioBufferSourceNode.prototype.noteOff; - } - if (typeof OscillatorNode.prototype.start !== "function"){ - OscillatorNode.prototype.start = OscillatorNode.prototype.noteOn; - } - if (typeof OscillatorNode.prototype.stop !== "function"){ - OscillatorNode.prototype.stop = OscillatorNode.prototype.noteOff; - } - //extend the connect function to include Tones - AudioNode.prototype._nativeConnect = AudioNode.prototype.connect; - AudioNode.prototype.connect = function(B){ - if (B.input && B.input instanceof GainNode){ - this._nativeConnect(B.input); - } else { - this._nativeConnect.apply(this, arguments); - } - } - - /////////////////////////////////////////////////////////////////////////// - // TONE - // @constructor - /////////////////////////////////////////////////////////////////////////// - - var Tone = function(){ - this.input = audioContext.createGain(); - this.output = audioContext.createGain(); - } - - /////////////////////////////////////////////////////////////////////////// - // CLASS VARS - /////////////////////////////////////////////////////////////////////////// - - Tone.prototype.context = audioContext; - Tone.prototype.fadeTime = .005; //5ms - Tone.prototype.bufferSize = 2048; //default buffer size - Tone.prototype.waveShaperResolution = 1024; //default buffer size - - /////////////////////////////////////////////////////////////////////////// - // CLASS METHODS - /////////////////////////////////////////////////////////////////////////// - - //@returns {number} the currentTime from the AudioContext - Tone.prototype.now = function(){ - return audioContext.currentTime; - } - - //@param {AudioParam | Tone} unit - Tone.prototype.connect = function(unit){ - this.output.connect(unit); - } - - //disconnect the output - Tone.prototype.disconnect = function(){ - this.output.disconnect(); - } - - //connect together an array of units in series - //@param {...AudioParam | Tone} units - Tone.prototype.chain = function(){ - if (arguments.length > 1){ - var currentUnit = arguments[0]; - for (var i = 1; i < arguments.length; i++){ - var toUnit = arguments[i]; - currentUnit.connect(toUnit); - currentUnit = toUnit; - } - } - } - - //set the output volume - //@param {number} vol - Tone.prototype.setVolume = function(vol){ - this.output.gain.value = vol; - } - - //fade the output volume - //@param {number} value - //@param {number=} duration (in seconds) - Tone.prototype.fadeTo = function(value, duration){ - this.defaultArg(duration, this.fadeTime); - this.rampToValue(this.output.gain, value, duration); - } - - - /////////////////////////////////////////////////////////////////////////// - // UTILITIES / HELPERS - /////////////////////////////////////////////////////////////////////////// - - function isUndef(val){ - return typeof val === "undefined"; - } - - //ramps to value linearly starting now - //@param {AudioParam} audioParam - //@param {number} value - //@param {number=} duration (in seconds) - Tone.prototype.rampToValueNow = function(audioParam, value, duration){ - var currentValue = audioParam.value; - var now = this.now(); - duration = this.defaultArg(duration, this.fadeTime); - audioParam.setValueAtTime(currentValue, now); - audioParam.linearRampToValueAtTime(value, now + this.toSeconds(duration)); - } - - //ramps to value exponentially starting now - //@param {AudioParam} audioParam - //@param {number} value - //@param {number=} duration (in seconds) - Tone.prototype.exponentialRampToValueNow = function(audioParam, value, duration){ - var currentValue = audioParam.value; - var now = this.now(); - audioParam.setValueAtTime(currentValue, now); - audioParam.exponentialRampToValueAtTime(value, now + this.toSeconds(duration)); - } - - //if the given argument is undefined, go with the default - //@param {*} given - //@param {*} fallback - //@returns {*} - Tone.prototype.defaultArg = function(given, fallback){ - return isUndef(given) ? fallback : given; - } - - //@param {number} percent (0-1) - //@returns {number} the equal power gain (0-1) - //good for cross fades - Tone.prototype.equalPowerScale = function(percent){ - return Math.sin((percent) * 0.5*Math.PI); - } - - //@param {number} gain - //@returns {number} gain (decibel scale but betwee 0-1) - Tone.prototype.logScale = function(gain) { - return Math.max(this.normalize(this.gainToDb(gain), -100, 0), 0); - } - - //@param {number} gain - //@returns {number} gain (decibel scale but betwee 0-1) - Tone.prototype.expScale = function(gain) { - return this.dbToGain(this.interpolate(gain, -100, 0)); - } - - //@param {number} db - //@returns {number} gain - Tone.prototype.dbToGain = function(db) { - return Math.pow(2, db / 6); - } - - //@param {number} gain - //@returns {number} db - Tone.prototype.gainToDb = function(gain) { - return 20 * (Math.log(gain) / Math.LN10); - } - - //@param {number} input 0 to 1 - //@returns {number} between outputMin and outputMax - Tone.prototype.interpolate = function(input, outputMin, outputMax){ - return input*(outputMax - outputMin) + outputMin; - } - - //@returns {number} 0-1 - Tone.prototype.normalize = function(input, inputMin, inputMax){ - //make sure that min < max - if (inputMin > inputMax){ - var tmp = inputMax; - inputMax = inputMin; - inputMin = tmp; - } else if (inputMin == inputMax){ - return 0; - } - return (input - inputMin) / (inputMax - inputMin); - } - - - //@param {number} samples - //@returns {number} the number of seconds - Tone.prototype.samplesToSeconds = function(samples){ - return samples / audioContext.sampleRate; - } - - /////////////////////////////////////////////////////////////////////////// - // TIMING - // - // numbers are passed through - // '+' prefixed values will be "now" relative - /////////////////////////////////////////////////////////////////////////// - - //@typedef {string|number} - Tone.Timing; - - //@param {Tone.Timing} timing - //@param {number=} bpm - //@param {number=} timeSignature - //@returns {number} the time in seconds - Tone.prototype.toSeconds = function(time, bpm, timeSignature){ - if (typeof time === "number"){ - return time; //assuming that it's seconds - } else if (typeof time === "string"){ - var plusTime = 0; - if(time.charAt(0) === "+") { - plusTime = this.now(); - time = time.slice(1); - } - if (this.isNotation(time)){ - time = this.notationToSeconds(time, bpm, timeSignature); - } else if (this.isTransportTime(time)){ - time = this.transportTimeToSeconds(time, bpm, timeSignature); - } else if (this.isFrequency(time)){ - time = this.frequencyToSeconds(time); - } - return parseFloat(time) + plusTime; - } - } - - //@param {number|string} timing - //@param {number=} bpm - //@param {number=} timeSignature - //@returns {number} the time in seconds - Tone.prototype.toFrequency = function(time, bpm, timeSignature){ - if (this.isNotation(time) || this.isFrequency(time)){ - return this.secondsToFrequency(this.toSeconds(time, bpm, timeSignature)); - } else { - return time; - } - } - - //@returns {number} the tempo - //meant to be overriden by Transport - Tone.prototype.getBpm = function(){ - return 120; - } - - //@returns {number} the time signature / 4 - //meant to be overriden by Transport - Tone.prototype.getTimeSignature = function(){ - return 4; - } - - /////////////////////////////////////////////////////////////////////////// - // TIMING CONVERSIONS - /////////////////////////////////////////////////////////////////////////// - - //@param {string} note - //@returns {boolean} if the value is in notation form - Tone.prototype.isNotation = (function(){ - var notationFormat = new RegExp(/[0-9]+[mnt]$/i); - return function(note){ - return notationFormat.test(note); - } - })(); - - //@param {string} transportTime - //@returns {boolean} if the value is in notation form - Tone.prototype.isTransportTime = (function(){ - var transportTimeFormat = new RegExp(/^\d+(\.\d+)?:\d+(\.\d+)?(:\d+(\.\d+)?)?$/); - return function(transportTime){ - return transportTimeFormat.test(transportTime); - } - })(); - - //@param {string} freq - //@returns {boolean} if the value is in notation form - Tone.prototype.isFrequency = (function(){ - var freqFormat = new RegExp(/[0-9]+hz$/i); - return function(freq){ - return freqFormat.test(freq); - } - })(); - - // 4n == quarter note; 16t == sixteenth note triplet; 1m == 1 measure - //@param {string} notation - //@param {number=} bpm - //@param {number} timeSignature (default 4) - //@returns {number} time duration of notation - Tone.prototype.notationToSeconds = function(notation, bpm, timeSignature){ - bpm = this.defaultArg(bpm, this.getBpm()); - timeSignature = this.defaultArg(timeSignature, this.getTimeSignature()); - var beatTime = (60 / bpm); - var subdivision = parseInt(notation, 10); - var beats = 0; - if (subdivision === 0){ - beats = 0; - } - var lastLetter = notation.slice(-1); - if (lastLetter === "t"){ - beats = (4 / subdivision) * 2/3 - } else if (lastLetter === 'n'){ - beats = 4 / subdivision - } else if (lastLetter === 'm'){ - beats = subdivision * timeSignature; - } else { - beats = 0; - } - return beatTime * beats; - } - - // 4:2:3 == 4 measures + 2 quarters + 3 sixteenths - //@param {string} transportTime - //@param {number=} bpm - //@param {number=} timeSignature (default 4) - //@returns {number} time duration of notation - Tone.prototype.transportTimeToSeconds = function(transportTime, bpm, timeSignature){ - bpm = this.defaultArg(bpm, this.getBpm()); - timeSignature = this.defaultArg(timeSignature, this.getTimeSignature()); - var measures = 0; - var quarters = 0; - var sixteenths = 0; - var split = transportTime.split(":"); - if (split.length === 2){ - measures = parseFloat(split[0]); - quarters = parseFloat(split[1]); - } else if (split.length === 1){ - quarters = parseFloat(split[0]); - } else if (split.length === 3){ - measures = parseFloat(split[0]); - quarters = parseFloat(split[1]); - sixteenths = parseFloat(split[2]); - } - var beats = (measures * timeSignature + quarters + sixteenths / 4); - return beats * this.notationToSeconds("4n", bpm, timeSignature); - } - - //@param {string | number} freq (i.e. 440hz) - //@returns {number} the time of a single cycle - Tone.prototype.frequencyToSeconds = function(freq){ - return 1 / parseFloat(freq); - } - - //@param {number} seconds - //@param {number=} bpm - //@param {number=} - //@returns {string} the seconds in transportTime - Tone.prototype.secondsToTransportTime = function(seconds, bpm, timeSignature){ - bpm = this.defaultArg(bpm, this.getBpm()); - timeSignature = this.defaultArg(timeSignature, this.getTimeSignature()); - var quarterTime = this.notationToSeconds("4n", bpm, timeSignature); - var quarters = seconds / quarterTime; - var measures = parseInt(quarters / timeSignature, 10); - var sixteenths = parseInt((quarters % 1) * 4, 10); - quarters = parseInt(quarters, 10) % timeSignature; - var progress = [measures, quarters, sixteenths]; - return progress.join(":"); - } - - //@param {number} seconds - //@returns {number} the frequency - Tone.prototype.secondsToFrequency = function(seconds){ - return 1/seconds - } - - /////////////////////////////////////////////////////////////////////////// - // STATIC METHODS - /////////////////////////////////////////////////////////////////////////// - - //based on closure library 'inherit' function - Tone.extend = function(child, parent){ - if (isUndef(parent)){ - parent = Tone; - } - /** @constructor */ - function tempConstructor() {}; - tempConstructor.prototype = parent.prototype; - child.prototype = new tempConstructor(); - /** @override */ - child.prototype.constructor = child; - } - - Tone.context = audioContext; - - return Tone; -})); - -/////////////////////////////////////////////////////////////////////////////// -// -// SIGNAL -// -// audio-rate value -// useful for controlling AudioParams -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/signal/Signal',["Tone/core/Tone"], function(Tone){ - - //@param {number=} value - Tone.Signal = function(value){ - Tone.call(this); - - //components - this.signal = this.context.createWaveShaper(); - this.scalar = this.context.createGain(); - //generator to drive values - this.generator = this.context.createOscillator(); - - //connections - this.chain(this.generator, this.signal, this.scalar, this.output); - //pass values through - this.input.connect(this.output); - - //setup - this.generator.start(0); - this._signalCurve(); - this.setValue(this.defaultArg(value, 0)); - - } - - Tone.extend(Tone.Signal); - - //generates a constant output of 1 - Tone.Signal.prototype._signalCurve = function(){ - var len = 8; - var curve = new Float32Array(len); - for (var i = 0; i < len; i++){ - //all inputs produce the output value - curve[i] = 1; - } - //console.log(curve); - this.signal.curve = curve; - } - - //@returns {number} - Tone.Signal.prototype.getValue = function(){ - return this.scalar.gain.value; - } - - //@param {number} val - Tone.Signal.prototype.setValue = function(val){ - this.scalar.gain.value = val; - } - - //all of the automation curves are available - //@param {number} value - //@param {Tone.Timing} time - Tone.Signal.prototype.setValueAtTime = function(value, time){ - - this.scalar.gain.setValueAtTime(value, this.toSeconds(time)); - } - - //@param {number} value - //@param {Tone.Timing} endTime - Tone.Signal.prototype.linearRampToValueAtTime = function(value, endTime){ - this.scalar.gain.linearRampToValueAtTime(value, this.toSeconds(endTime)); - } - - //@param {number} value - //@param {Tone.Timing} endTime - Tone.Signal.prototype.exponentialRampToValueAtTime = function(value, endTime){ - this.scalar.gain.exponentialRampToValueAtTime(value, this.toSeconds(endTime)); - } - - //@param {number} value - //@param {Tone.Timing} startTime - //@param {number} timeConstant - Tone.Signal.prototype.setTargetAtTime = function(target, startTime, timeConstant){ - this.scalar.gain.setTargetAtTime(target, this.toSeconds(startTime), timeConstant); - } - - //@param {number} value - //@param {Tone.Timing} startTime - //@param {Tone.Timing} duration - Tone.Signal.prototype.setValueCurveAtTime = function(values, startTime, duration){ - this.scalar.gain.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration)); - } - - //@param {Tone.Timing} startTime - Tone.Signal.prototype.cancelScheduledValues = function(startTime){ - this.scalar.gain.cancelScheduledValues(this.toSeconds(startTime)); - } - - return Tone.Signal; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// ADD -// -// adds a value to the incoming signal -// can sum two signals or a signal and a constant -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/signal/Add',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ - - //@param {Tone.Signal|number} value - Tone.Add = function(value){ - Tone.call(this); - - if (typeof value === "number"){ - this.value = new Tone.Signal(value); - } else { - this.value = value; - } - - //connections - this.chain(this.value, this.input, this.output); - } - - Tone.extend(Tone.Add); - - //set the constant value - //@param {number} value - Tone.Add.prototype.setValue = function(value){ - this.value.setValue(value); - } - - return Tone.Add; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// MULTIPLY -// -// Multiply the incoming signal by a factor -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/signal/Multiply',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ - - //@param {number} value - Tone.Multiply = function(value){ - Tone.call(this); - this.input.connect(this.output); - this.input.gain.value = value; - } - - Tone.extend(Tone.Multiply); - - //set the constant value - //@param {number} value - Tone.Multiply.prototype.setValue = function(value){ - this.input.gain.value = value; - } - - return Tone.Multiply; -}) -; -/////////////////////////////////////////////////////////////////////////////// -// -// SCALE -// -// performs linear scaling on an input signal between inputMin and inputMax -// to output the range outputMin outputMax -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/signal/Scale',["Tone/core/Tone", "Tone/signal/Add", "Tone/signal/Multiply"], function(Tone){ - - //@param {number} inputMin - //@param {number} inputMax - //@param {number=} outputMin - //@param {number=} outputMax - Tone.Scale = function(inputMin, inputMax, outputMin, outputMax){ - Tone.call(this); - - if (arguments.length == 2){ - outputMin = inputMin; - outputMax = inputMax; - inputMin = -1; - inputMax = 1; - } - //components - this.plusInput = new Tone.Add(-inputMin); - this.scale = new Tone.Multiply((outputMax - outputMin)/(inputMax - inputMin)); - this.plusOutput = new Tone.Add(outputMin); - - //connections - this.chain(this.input, this.plusInput, this.scale, this.plusOutput, this.output); - } - - //extend StereoSplit - Tone.extend(Tone.Scale); - - - return Tone.Scale; -}); - -/////////////////////////////////////////////////////////////////////////////// -// -// DRY/WET KNOB -// -// equal power fading -// control values: -// 0 = 100% dry -// 1 = 100% wet -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/component/DryWet',["Tone/core/Tone", "Tone/signal/Signal", "Tone/signal/Scale"], function(Tone){ - - Tone.DryWet = function(initialDry){ - Tone.call(this); - - //components - this.dry = this.context.createGain(); - this.wet = this.context.createGain(); - //control signal - this.control = new Tone.Signal(); - this.invert = new Tone.Scale(1, 0); - this.normal = new Tone.Scale(0, 1); - - //connections - this.dry.connect(this.output); - this.wet.connect(this.output); - //wet control - this.chain(this.control, this.invert, this.wet.gain); - //dry control - this.chain(this.control, this.normal, this.dry.gain); - - //setup - this.dry.gain.value = 0; - this.wet.gain.value = 0; - this.setDry(0); - } - - Tone.extend(Tone.DryWet); - - // @param {number} val - // @param {Tone.Timing} rampTime - Tone.DryWet.prototype.setDry = function(val, rampTime){ - rampTime = this.defaultArg(rampTime, 0); - this.control.linearRampToValueAtTime(val*2 - 1, this.toSeconds(rampTime)); - } - - Tone.DryWet.prototype.setWet = function(val, rampTime){ - this.setDry(1-val, rampTime); - } - - return Tone.DryWet; -}); - -/////////////////////////////////////////////////////////////////////////////// -// -// Envelope -// -// ADR envelope generator attaches to an AudioParam -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/component/Envelope',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){ - - - Tone.Envelope = function(attack, decay, sustain, release, minOutput, maxOutput){ - //extend Unit - Tone.call(this); - - //set the parameters - this.attack = this.defaultArg(attack, .01); - this.decay = this.defaultArg(decay, .1); - this.release = this.defaultArg(release, 1); - this.sustain = this.defaultArg(sustain, .5); - - // this.setSustain(this.defaultArg(sustain, .1)); - this.min = this.defaultArg(minOutput, 0); - this.max = this.defaultArg(maxOutput, 1); - - //the control signal - this.control = new Tone.Signal(this.min); - - //connections - this.chain(this.control, this.output); - } - - Tone.extend(Tone.Envelope, Tone); - - //attack->decay->sustain - //@param {Tone.Timing} time - Tone.Envelope.prototype.triggerAttack = function(time){ - var startVal = this.min; - if (!time){ - startVal = this.control.getValue(); - } - time = this.defaultArg(time, this.now()); - time = this.toSeconds(time); - this.control.cancelScheduledValues(time); - this.control.setValueAtTime(startVal, time); - var attackTime = this.toSeconds(this.attack); - var decayTime = this.toSeconds(this.decay); - this.control.linearRampToValueAtTime(this.max, time + attackTime); - var sustainVal = (this.max - this.min) * this.sustain + this.min; - this.control.linearRampToValueAtTime(sustainVal, time + attackTime + decayTime); - } - - //attack->decay->sustain - Tone.Envelope.prototype.triggerAttackExp = function(time){ - var startVal = this.min; - if (!time){ - startVal = this.control.getValue(); - } - time = this.defaultArg(time, this.now()); - time = this.toSeconds(time); - this.control.cancelScheduledValues(time); - this.control.setValueAtTime(startVal, time); - var attackTime = this.toSeconds(this.attack); - var decayTime = this.toSeconds(this.decay); - this.control.linearRampToValueAtTime(this.max, time + attackTime); - var sustainVal = (this.max - this.min) * this.sustain + this.min; - this.control.exponentialRampToValueAtTime(sustainVal, time + attackTime + decayTime); - } - - //triggers the release of the envelope - Tone.Envelope.prototype.triggerRelease = function(time){ - var startVal = this.control.getValue(); - if (time){ - startVal = (this.max - this.min) * this.sustain + this.min; - } - time = this.defaultArg(time, this.now()); - time = this.toSeconds(time); - this.control.cancelScheduledValues(time); - this.control.setValueAtTime(startVal, time); - this.control.linearRampToValueAtTime(this.min, time + this.toSeconds(this.release)); - } - - - //triggers the release of the envelope - Tone.Envelope.prototype.triggerReleaseExp = function(time){ - var startVal = this.control.getValue(); - if (time){ - startVal = (this.max - this.min) * this.sustain + this.min; - } - time = this.defaultArg(time, this.now()); - time = this.toSeconds(time); - this.control.cancelScheduledValues(time); - this.control.setValueAtTime(startVal, time); - this.control.exponentialRampToValueAtTime(this.min, time + this.toSeconds(this.release)); - } - - //@private - //pointer to the parent's connect method - Tone.Envelope.prototype._connect = Tone.prototype.connect; - - //triggers the release of the envelope - Tone.Envelope.prototype.connect = function(param){ - if (param instanceof AudioParam){ - //set the initial value - param.value = 0; - } - this._connect(param); - } - - return Tone.Envelope; -}); - -/////////////////////////////////////////////////////////////////////////////// -// -// OSCILLATOR -// -// just an oscillator, -// but starting and stopping is easier than the native version -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/source/Oscillator',["Tone/core/Tone"], function(Tone){ - - Tone.Oscillator = function(freq, type){ - Tone.call(this); - - this.started = false; - - //components - this.oscillator = this.context.createOscillator(); - this.oscillator.frequency.value = this.defaultArg(this.toFrequency(freq), 440); - this.oscillator.type = this.defaultArg(type, "sine"); - //connections - this.chain(this.oscillator, this.output); - } - - Tone.extend(Tone.Oscillator); - - //@param {number=} time - Tone.Oscillator.prototype.start = function(time){ - if (!this.started){ - var freq = this.oscillator.frequency.value; - var type = this.oscillator.type; - var detune = this.oscillator.frequency.value; - this.oscillator = this.context.createOscillator(); - this.oscillator.frequency.value = freq; - this.oscillator.type = type; - this.oscillator.detune.value = detune; - this.oscillator.connect(this.output); - this.started = true; - time = this.defaultArg(time, this.now()); - this.oscillator.start(time); - } - } - - //@param {number=} time - Tone.Oscillator.prototype.stop = function(time){ - if (this.started){ - time = this.defaultArg(time, this.now()); - this.oscillator.stop(time); - this.started = false; - } - } - - //@param {number} val - //@param {Tone.Timing=} rampTime - Tone.Oscillator.prototype.setFrequency = function(val, rampTime){ - rampTime = this.defaultArg(rampTime, 0); - this.oscillator.frequency.linearRampToValueAtTime(this.toFrequency(val), this.toSeconds(rampTime)); - } - - //@param {string} type - Tone.Oscillator.prototype.setType = function(type){ - this.oscillator.type = type; - } - - return Tone.Oscillator; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// LFO -// -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/component/LFO',["Tone/core/Tone", "Tone/source/Oscillator", "Tone/signal/Scale"], function(Tone){ - - Tone.LFO = function(rate, outputMin, outputMax){ - //extends Unit - Tone.call(this); - - //defaults - rate = this.defaultArg(rate, 1); - min = this.defaultArg(outputMin, -1); - max = this.defaultArg(outputMax, 1); - - //the components - this.oscillator = new Tone.Oscillator(rate, "sine"); - this.scaler = new Tone.Scale(min, max); - - //connect it up - this.chain(this.oscillator, this.scaler, this.output); - } - - Tone.extend(Tone.LFO, Tone); - - - //start the lfo - Tone.LFO.prototype.start = function(time){ - this.oscillator.start(time); - } - - //stop - Tone.LFO.prototype.stop = function(time){ - this.oscillator.stop(time); - } - - - //set the params - Tone.LFO.prototype.setFrequency = function(rate){ - this.oscillator.setFrequency(rate); - } - - //set the params - Tone.LFO.prototype.setMin = function(min){ - this.scaler.setMin(min); - } - - //set the params - Tone.LFO.prototype.setMax = function(max){ - this.scaler.setMax(max); - } - - //set the waveform of the LFO - //@param {string | number} type ('sine', 'square', 'sawtooth', 'triangle', 'custom'); - Tone.LFO.prototype.setType = function(type){ - this.oscillator.setType(type); - } - - //@private - //pointer to the parent's connect method - Tone.LFO.prototype._connect = Tone.prototype.connect; - - //triggers the release of the envelope - Tone.LFO.prototype.connect = function(param){ - if (param instanceof AudioParam){ - //set the initial value - param.value = 0; - } - this._connect(param); - } - - return Tone.LFO; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// MASTER OUTPUT -// -// a single master output -// adds a toMaster method on AudioNodes and components -/////////////////////////////////////////////////////////////////////////////// - - -define('Tone/core/Master',["Tone/core/Tone"], function(Tone){ - - var Master = function(){ - //extend audio unit - Tone.call(this); - - //put a hard limiter on the output so we don't blow any eardrums - 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); - } - - Tone.extend(Master); - - /////////////////////////////////////////////////////////////////////////// - // Add toMaster methods - /////////////////////////////////////////////////////////////////////////// - - //@param {AudioNode|Tone=} unit - Tone.prototype.toMaster = function(){ - this.connect(Tone.Master); - } - - AudioNode.prototype.toMaster = function(){ - this.connect(Tone.Master); - } - - //a single master output - Tone.Master = new Master(); - - return Tone.Master; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// METER -// -// get the rms of the input signal with some averaging -// -// inspired by https://github.com/cwilso/volume-meter/blob/master/volume-meter.js -// The MIT License (MIT) Copyright (c) 2014 Chris Wilson -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/component/Meter',["Tone/core/Tone", "Tone/core/Master"], function(Tone){ - - //@param {number=} channels - Tone.Meter = function(channels){ - //extends Unit - Tone.call(this); - - this.channels = this.defaultArg(channels, 1); - this.volume = new Array(this.channels); - this.values = new Array(this.channels); - //zero out the volume array - for (var i = 0; i < this.channels; i++){ - this.volume[i] = 0; - this.values[i] = 0; - } - this.clipTime = 0; - - //components - this.jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, this.channels); - this.jsNode.onaudioprocess = this.onprocess.bind(this); - - //signal just passes - this.input.connect(this.output); - this.input.connect(this.jsNode); - //so it doesn't get garbage collected - this.jsNode.toMaster(); - } - - Tone.extend(Tone.Meter, Tone); - - - //@param {number=} channel - //@returns {number} - Tone.Meter.prototype.getLevel = function(channel){ - channel = this.defaultArg(channel, 0); - var vol = this.volume[channel]; - if (vol < .00001){ - return 0; - } else { - return vol; - } - } - - //@param {number=} channel - //@returns {number} - Tone.Meter.prototype.getValue = function(channel){ - channel = this.defaultArg(channel, 0); - return this.values[channel]; - } - - //@param {number=} channel - //@returns {number} the channel volume in decibels - Tone.Meter.prototype.getDb = function(channel){ - return this.gainToDb(this.getLevel(channel)); - } - - // @returns {boolean} if the audio has clipped in the last 500ms - Tone.Meter.prototype.isClipped = function(){ - return Date.now() - this.clipTime < 500; - } - - //get the max value - Tone.Meter.prototype.onprocess = function(event){ - var bufferSize = this.jsNode.bufferSize; - for (var channel = 0; channel < this.channels; channel++){ - var input = event.inputBuffer.getChannelData(channel); - var sum = 0; - var total = 0; - var x; - var clipped = false; - for (var i = 0; i < bufferSize; i++){ - x = input[i]; - if (!clipped && x > .95){ - clipped = true; - this.clipTime = Date.now(); - } - total += x; - sum += x * x; - } - var average = total / bufferSize; - var rms = Math.sqrt(sum / bufferSize); - this.volume[channel] = Math.max(rms, this.volume[channel] * .8); - this.values[channel] = average; - } - } - - return Tone.Meter; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// MERGE -// -// Merge a left and a right into a single left/right channel -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/signal/Merge',["Tone/core/Tone"], function(Tone){ - - Tone.Merge = function(){ - Tone.call(this); - - //components - this.left = this.context.createGain(); - this.right = this.context.createGain(); - this.merger = this.context.createChannelMerger(2); - - //connections - this.left.connect(this.merger, 0, 0); - this.right.connect(this.merger, 0, 1); - this.merger.connect(this.output); - } - - Tone.extend(Tone.Merge); - - return Tone.Merge; -}) -; -/////////////////////////////////////////////////////////////////////////////// -// -// PANNER -// -// Equal Power Gain L/R Panner. Not 3D -// 0 = 100% Left -// 1 = 100% Right -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/component/Panner',["Tone/core/Tone", "Tone/signal/Merge", "Tone/signal/Signal", "Tone/signal/Scale"], -function(Tone){ - - Tone.Panner = function(){ - Tone.call(this); - - //components - //incoming signal is sent to left and right - this.left = this.context.createGain(); - this.right = this.context.createGain(); - this.control = new Tone.Signal(); - this.merge = new Tone.Merge(); - this.invert = new Tone.Scale(1, 0); - this.normal = new Tone.Scale(0, 1); - - //connections - this.chain(this.input, this.left, this.merge.left); - this.chain(this.input, this.right, this.merge.right); - this.merge.connect(this.output); - //left channel control - this.chain(this.control, this.invert, this.left.gain); - //right channel control - this.chain(this.control, this.normal, this.right.gain); - - - //setup - this.left.gain.value = 0; - this.right.gain.value = 0; - this.setPan(.5); - } - - Tone.extend(Tone.Panner); - - Tone.Panner.prototype.setPan = function(val, rampTime){ - rampTime = this.defaultArg(rampTime, 0); - //put val into -1 to 1 range - this.control.linearRampToValueAtTime(val * 2 - 1, rampTime); - } - - return Tone.Panner; -});; -/////////////////////////////////////////////////////////////////////////////// -// -// BUS -// -// buses are another way of routing audio -// -// adds: send(channelName, amount) -// receive(channelName) -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/core/Bus',["Tone/core/Tone"], function(Tone){ - - var Buses = {} - - //@param {string} channelName - //@param {number=} amount - //@returns {GainNode} the send - Tone.prototype.send = function(channelName, amount){ - if (!Buses.hasOwnProperty(channelName)){ - Buses[channelName] = this.context.createGain(); - } - var sendKnob = this.context.createGain(); - sendKnob.gain.value = this.defaultArg(amount, 1); - this.chain(this.output, sendKnob, Buses[channelName]); - return sendKnob; - } - - //@param {string} channelName - Tone.prototype.receive = function(channelName){ - if (!Buses.hasOwnProperty(channelName)){ - Buses[channelName] = this.context.createGain(); - } - Buses[channelName].connect(this.input); - } - - Tone.Buses = Buses; - - return Tone.Buses; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// TRANSPORT -// -// oscillator-based transport allows for simple musical timing -// supports tempo curves and time changes -// setInterval (repeated events) -// setTimeout (single timeline event) -// -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/core/Transport',["Tone/core/Tone", "Tone/core/Master"], function(Tone){ - - var Transport = function(){ - - //components - this.oscillator = null; - this.jsNode = this.context.createScriptProcessor(this.bufferSize, 1, 1); - this.jsNode.onaudioprocess = this._processBuffer.bind(this); - - - //privates - this._timeSignature = 4;//defaults to 4/4 - this._tatum = 12; //subdivisions of the quarter note - this._ticks = 0; //the number of tatums - this._upTick = false; // if the wave is on the rise or fall - this._bpm = 120; //defaults to 120 - //@type {Array.} - this._intervals = []; - //@type {Array.} - this._timeouts = []; - this._timeoutProgress = 0; - - //public - this._loopStart = 0; - this._loopEnd = this._tatum * 4; - this.loop = false; - this.state = Transport.state.stopped; - - //so it doesn't get garbage collected - this.jsNode.toMaster(); - } - - Tone.extend(Transport); - - /////////////////////////////////////////////////////////////////////////////// - // INTERNAL METHODS - /////////////////////////////////////////////////////////////////////////////// - - Transport.prototype._processBuffer = function(event){ - var now = this.defaultArg(event.playbackTime, this.now()); - var bufferSize = this.jsNode.bufferSize; - var endTime = now + this.samplesToSeconds(bufferSize); - var incomingBuffer = event.inputBuffer.getChannelData(0); - var upTick = this._upTick; - for (var i = 0; i < bufferSize; i++){ - var sample = incomingBuffer[i]; - if (sample > 0 && !upTick){ - upTick = true; - this._processTick(now + this.samplesToSeconds(i)); - } else if (sample < 0 && upTick){ - upTick = false; - } - } - this._upTick = upTick; - } - - //@param {number} tickTime - Transport.prototype._processTick = function(tickTime){ - //do the looping stuff - var ticks = this._ticks; - //do the intervals - this._processIntervals(ticks, tickTime); - this._processTimeouts(ticks, tickTime); - this._ticks = ticks + 1; - if (this.loop){ - if (this._ticks === this._loopEnd){ - this._setTicks(this._loopStart); - } - } - } - - //jump to a specific tick in the timeline - Transport.prototype._setTicks = function(ticks){ - this._ticks = ticks; - for (var i = 0; i < this._timeouts.length; i++){ - var timeout = this._timeouts[i]; - if (timeout.callbackTick() >= ticks){ - this._timeoutProgress = i; - break; - } - } - } - - /////////////////////////////////////////////////////////////////////////////// - // TIMING - /////////////////////////////////////////////////////////////////////////////// - - - //processes and invokes the intervals - Transport.prototype._processIntervals = function(ticks, time){ - for (var i = 0, len = this._intervals.length; i ticks){ - break; - } - } - } - - - //@param {function(number)} callback - //@param {string} interval (01:02:0.2) - //@param {Object=} ctx the 'this' object which the - //@returns {Transport.Event} the event - Transport.prototype.setInterval = function(callback, interval, ctx){ - var ticks = this.toTicks(interval); - ctx = this.defaultArg(ctx, window); - var timeout = new Transport.Timeout(callback, ctx, ticks, this._ticks); - this._intervals.push(timeout); - return timeout; - } - - //@param {number} intervalId - //@param {} - //@returns {boolean} true if the interval was removed - Transport.prototype.clearInterval = function(rmInterval){ - for (var i = 0; i < this._intervals.length; i++){ - var interval = this._intervals[i]; - if (interval === rmInterval){ - this._intervals.splice(i, 1); - return true; - } - } - return false; - } - - //@param {function(number)} callback - //@param {string} timeout colon seperated (bars:beats) - //@param {Object=} ctx the 'this' object which the - //@returns {number} the timeoutID - Transport.prototype.setTimeout = function(callback, timeout, ctx){ - var ticks = this.toTicks(timeout); - ctx = this.defaultArg(ctx, window); - var timeout = new Transport.Timeout(callback, ctx, ticks, this._ticks); - //put it in the right spot - this._addTimeout(timeout); - return timeout; - } - - //@param {function(number)} callback - //@param {string} timeout colon seperated (bars:beats) - //@param {Object=} ctx the 'this' object which the - //@returns {number} the timeoutID - //like setTimeout, but to absolute timeline positions instead of 'now' relative - //events which have passed will not be called - Transport.prototype.setTimeline = function(callback, timeout, ctx){ - var ticks = this.toTicks(timeout); - ctx = this.defaultArg(ctx, window); - var timeout = new Transport.Timeout(callback, ctx, ticks, 0); - //put it in the right spot - this._addTimeout(timeout); - return timeout; - } - - //add an event in the correct position - Transport.prototype._addTimeout = function(event){ - for (var i = this._timeoutProgress, len = this._timeouts.length; i event.callbackTick()){ - this._timeouts.splice(i, 0, event); - return; - } - } - //otherwise push it on the end - this._timeouts.push(event); - } - - //@param {string} timeoutID returned by setTimeout - Transport.prototype.clearTimeout = function(timeoutID){ - for (var i = 0; i < this._timeouts.length; i++){ - var timeout = this._timeouts[i]; - if (timeout.id === timeoutID){ - this._timeouts.splice(i, 1); - return true; - } - } - return false; - } - - //@param {string|number} time - //@returns {number} the the conversion to ticks - Transport.prototype.toTicks = function(time){ - //get the seconds - var seconds = this.toSeconds(time); - var quarter = this.notationToSeconds("4n"); - var quarters = seconds / quarter; - var ticks = quarters * this._tatum; - //quantize to tick value - return Math.round(ticks); - } - - //@param {number} ticks - //@returns {string} progress (measures:beats:sixteenths) - Transport.prototype.ticksToTransportTime = function(ticks){ - var quarters = ticks / this._tatum; - var measures = parseInt(quarters / this._timeSignature, 10); - var sixteenths = parseInt((quarters % 1) * 4, 10); - quarters = parseInt(quarters, 10) % this._timeSignature; - var progress = [measures, quarters, sixteenths]; - return progress.join(":"); - } - - //@returns {string} progress (measures:beats:sixteenths) - Transport.prototype.getTransportTime = function(){ - return this.ticksToTransportTime(this._ticks); - } - - //jump to a specific measure - //@param {string} progress - Transport.prototype.setTransportTime = function(progress){ - var ticks = this.toTicks(progress); - this._setTicks(ticks); - } - - /////////////////////////////////////////////////////////////////////////////// - // START/STOP/PAUSE - /////////////////////////////////////////////////////////////////////////////// - - Transport.prototype.start = function(time){ - if (this.state !== Transport.state.started){ - this.state = Transport.state.started; - this.upTick = false; - time = this.defaultArg(time, this.now()); - this.oscillator = this.context.createOscillator(); - this.oscillator.type = "square"; - this.setBpm(this._bpm); - this.oscillator.connect(this.jsNode); - this.oscillator.start(this.toSeconds(time)); - } - } - - Transport.prototype.stop = function(time){ - if (this.state !== Transport.state.stopped){ - this.state = Transport.state.stopped; - time = this.defaultArg(time, this.now()); - this.oscillator.stop(this.toSeconds(time)); - this._setTicks(0); - } - } - - Transport.prototype.pause = function(time){ - this.state = Transport.state.paused; - time = this.defaultArg(time, this.now()); - this.oscillator.stop(this.toSeconds(time)); - } - - /////////////////////////////////////////////////////////////////////////////// - // SETTERS/GETTERS - /////////////////////////////////////////////////////////////////////////////// - - //@param {number} bpm - //@param {number=} rampTime Optionally speed the tempo up over time - Transport.prototype.setBpm = function(bpm, rampTime){ - this._bpm = bpm; - if (this.state === Transport.state.started){ - //convert the bpm to frequency - var tatumFreq = this.toFrequency(this._tatum.toString() + "n", this._bpm, this._timeSignature); - var freqVal = 4 * tatumFreq; - if (!rampTime){ - this.oscillator.frequency.value = freqVal; - } else { - this.exponentialRampToValueNow(this.oscillator.frequency, freqVal, rampTime); - } - } - } - - //@returns {number} the current bpm - Transport.prototype.getBpm = function(){ - //if the oscillator isn't running, return _bpm - if (this.state === Transport.state.started){ - //convert the current frequency of the oscillator to bpm - var freq = this.oscillator.frequency.value; - return 60 * (freq / this._tatum); - } else { - return this._bpm; - } - } - - //@param {number} numerator - //@param {number=} denominator - Transport.prototype.setTimeSignature = function(numerator, denominator){ - denominator = this.defaultArg(denominator, 4); - this._timeSignature = numerator / (denominator / 4); - } - - //@returns {number} the time signature - Transport.prototype.getTimeSignature = function(){ - return this._timeSignature; - } - - //@param {number|string} startPosition - Transport.prototype.setLoopStart = function(startPosition){ - this._loopStart = this.toTicks(startPosition); - } - - //@param {number|string} endPosition - Transport.prototype.setLoopEnd = function(endPosition){ - this._loopEnd = this.toTicks(endPosition); - } - - //@enum - Transport.state = { - started : "started", - paused : "paused", - stopped : "stopped" - } - - /////////////////////////////////////////////////////////////////////////////// - // - // TRANSPORT EVENT - // - /////////////////////////////////////////////////////////////////////////////// - - //@constructor - //@param {function(number)} callback - //@param {object} context - //@param {number} interval (in ticks) - //@param {number} startTicks - //@param {boolean} repeat - Transport.Timeout = function(callback, context, interval, startTicks){ - this.interval = interval; - this.start = startTicks; - this.callback = callback; - this.context = context; - } - - Transport.Timeout.prototype.doCallback = function(playbackTime){ - this.callback.call(this.context, playbackTime); - } - - Transport.Timeout.prototype.callbackTick = function(){ - return this.start + this.interval; - } - - Transport.Timeout.prototype.testCallback = function(tick){ - return (tick - this.start) % this.interval === 0; - } - - //a single transport object - Tone.Transport = new Transport(); - - /////////////////////////////////////////////////////////////////////////////// - // override Tone's getBpm and getTimeSignature with transport value - /////////////////////////////////////////////////////////////////////////////// - - //@returns {number} - Tone.prototype.getBpm = function(){ - return Tone.Transport.getBpm(); - } - - //@returns {number} - Tone.prototype.getTimeSignature = function(){ - return Tone.Transport.getTimeSignature(); - } - - - return Tone.Transport; -}); - -/////////////////////////////////////////////////////////////////////////////// -// -// EFFECTS UNIT -// -// connect the effect to the effectSend and to the effectReturn -// setDry(-1) = 100% Wet -// setDry(1) = 100% Dry -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/effects/Effect',["Tone/core/Tone", "Tone/component/DryWet"], function(Tone){ - - Tone.Effect = function(){ - //extends Unit - Tone.call(this); - - //components - this.dryWet = new Tone.DryWet(); - this.effectSend = this.context.createGain(); - this.effectReturn = this.context.createGain(); - - //connections - this.input.connect(this.dryWet.dry); - this.input.connect(this.effectSend); - this.effectReturn.connect(this.dryWet.wet); - this.dryWet.connect(this.output); - - //setup - this.setDry(0); - } - - Tone.extend(Tone.Effect, Tone); - - //adjust the dry/wet balance - //dryness -1 to 1 - // 1 = 100% dry - //-1 = 100% wet - //@param {number} dryness - //@param {number=} rampTime - Tone.Effect.prototype.setDry = function(dryness, rampTime){ - this.dryWet.setDry(dryness, rampTime) - } - - //@param {number} dryness - //@param {number=} rampTime - Tone.Effect.prototype.setWet = function(wetVal, rampTime){ - this.setDry(-wetVal, rampTime); - } - - Tone.Effect.prototype.bypass = function(){ - this.setDry(1, 0); - } - - Tone.Effect.prototype.connectEffect = function(effect){ - this.chain(this.effectSend, effect, this.effectReturn); - } - - return Tone.Effect; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// AUTO PANNER -// -// not a 3d panner. just LR -// -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/effects/AutoPanner',["Tone/core/Tone", "Tone/source/Oscillator", "Tone/component/Panner", "Tone/effects/Effect"], function(Tone){ - - - Tone.AutoPanner = function(rate, amount){ - Tone.Effect.call(this); - - //defaults - amount = this.defaultArg(amount, 1); - rate = this.defaultArg(rate, 1); - - //components - this.osc = new Tone.Oscillator(rate); - this.amount = this.context.createGain(); - this.panner = new Tone.Panner(); - - //connections - this.connectEffect(this.panner); - this.chain(this.osc, this.amount, this.panner.control); - } - - //extend Effect - Tone.extend(Tone.AutoPanner, Tone.Effect); - - Tone.AutoPanner.prototype.start = function(time){ - this.osc.start(time); - } - - Tone.AutoPanner.prototype.stop = function(time){ - this.osc.stop(time); - } - - Tone.AutoPanner.prototype.setType = function(type){ - this.osc.setType(type); - } - - Tone.AutoPanner.prototype.setFrequency = function(rate){ - this.osc.setFrequency(rate); - } - - Tone.AutoPanner.prototype.setAmount = function(amount){ - this.amount.gain.value = amount; - } - - return Tone.AutoPanner; -}); - -/////////////////////////////////////////////////////////////////////////////// -// -// FEEDBACK EFFECTS -// -// an effect with feedback -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/effects/FeedbackEffect',["Tone/core/Tone", "Tone/effects/Effect"], function(Tone){ - - Tone.FeedbackEffect = function(){ - //extends Unit - Tone.Effect.call(this); - - this.feedback = this.context.createGain(); - //feedback loop - this.chain(this.effectReturn, this.feedback, this.effectSend); - - //some initial values - this.setFeedback(0); - } - - Tone.extend(Tone.FeedbackEffect, Tone.Effect); - - Tone.FeedbackEffect.prototype.setFeedback = function(fback){ - this.rampToValueNow(this.feedback.gain, fback); - } - - return Tone.FeedbackEffect; -}); - -/////////////////////////////////////////////////////////////////////////////// -// -// FEEDBACK DELAY -// -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/effects/FeedbackDelay',["Tone/core/Tone", "Tone/effects/FeedbackEffect"], function(Tone){ - - //@param {number} delayTime - Tone.FeedbackDelay = function(delayTime){ - Tone.FeedbackEffect.call(this); - - this.delay = this.context.createDelay(4); - this.delay.delayTime.value = this.toSeconds(this.defaultArg(delayTime, .25)); - - //connect it up - this.connectEffect(this.delay); - } - - Tone.extend(Tone.FeedbackDelay, Tone.FeedbackEffect); - - Tone.FeedbackDelay.prototype.setDelayTime = function(delayTime){ - this.rampToValueNow(this.delay.delayTime, this.toSeconds(delayTime)); - } - - return Tone.FeedbackDelay; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// PING PONG DELAY -// -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/effects/PingPongDelay',["Tone/core/Tone", "Tone/effects/FeedbackDelay"], function(Tone){ - - - //@param {number=} delayTime - Tone.PingPongDelay = function(delayTime){ - Tone.StereoSplit.call(this); - - //components - this.leftDelay = new Tone.FeedbackDelay(delayTime); - this.rightDelay = new Tone.FeedbackDelay(delayTime); - - - //connect it up - this.connectLeft(this.leftDelay); - this.connectRight(this.rightDelay); - - //disconnect the feedback lines to connect them to the other delay - // http://jvzaudio.files.wordpress.com/2011/04/delay-f43.gif - this.leftDelay.feedback.disconnect(); - this.rightDelay.feedback.disconnect(); - this.leftDelay.feedback.connect(this.rightDelay.effectSend); - this.rightDelay.feedback.connect(this.leftDelay.effectSend); - - //initial vals; - this.setDelayTime(delayTime); - } - - Tone.extend(Tone.PingPongDelay, Tone.StereoSplit); - - //@param {number} delayTime - Tone.PingPongDelay.prototype.setDelayTime = function(delayTime){ - this.leftDelay.setDelayTime(delayTime); - this.rightDelay.setDelayTime(delayTime * 2); - } - - //@param {number} feedback (0 - 1) - Tone.PingPongDelay.prototype.setFeedback = function(feedback){ - this.leftDelay.setFeedback(feedback); - this.rightDelay.setFeedback(feedback); - } - - //@param {number} wet (0 - 1) - Tone.PingPongDelay.prototype.setWet = function(wet){ - this.leftDelay.setWet(wet); - this.rightDelay.setWet(wet); - } - - //@param {number} dry (0 - 1) - Tone.PingPongDelay.prototype.setDry = function(dry){ - this.leftDelay.setDry(dry); - this.rightDelay.setDry(dry); - } - - return Tone.PingPongDelay; -}); - -define('Tone/instrument/MonoSynth',["Tone/core/Tone", "Tone/component/Envelope", "Tone/source/Oscillator"], function(Tone){ - - - Tone.MonoSynth = function(){ - //one oscillator - this.oscillator = this.context.createOscillator(); - this.glideTime = .01; - this.filterEnvelope = new Tone.Envelope(); - } - - return Tone.MonoSynth; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// AUDIO PLAYER -// -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/source/Player',["Tone/core/Tone"], function(Tone){ - - Tone.Player = function(url){ - //extend Unit - Tone.call(this); - - //player vars - this.url = url; - this.source = null; - this.buffer = null; - - this.onended = function(){}; - } - - Tone.extend(Tone.Player, Tone); - - //makes an xhr for the buffer at the url - //invokes the callback at the end - //@param {function(Tone.Player)} callback - Tone.Player.prototype.load = function(callback){ - if (!this.buffer){ - var request = new XMLHttpRequest(); - request.open('GET', this.url, true); - request.responseType = 'arraybuffer'; - // decode asynchronously - var self = this; - request.onload = function() { - self.context.decodeAudioData(request.response, function(buff) { - self.buffer = buff; - if (callback){ - callback(self); - } - }); - } - //send the request - request.send(); - } else { - if (callback){ - callback(this); - } - } - } - - //play the buffer from start to finish at a time - Tone.Player.prototype.start = function(startTime, offset, duration, volume){ - if (this.buffer){ - //default args - startTime = this.defaultArg(startTime, this.now()); - offset = this.defaultArg(offset, 0); - duration = this.defaultArg(duration, this.buffer.duration - offset); - volume = this.defaultArg(volume, 1); - //make the source - this.source = this.context.createBufferSource(); - this.source.buffer = this.buffer; - this.source.loop = false; - this.source.start(this.toSeconds(startTime), this.toSeconds(offset), this.toSeconds(duration)); - this.source.onended = this._onended.bind(this); - var gain = this.context.createGain(); - gain.gain.value = volume; - this.chain(this.source, gain, this.output); - } - } - - //play the buffer from start to finish at a time - Tone.Player.prototype.loop = function(startTime, loopStart, loopEnd, offset, duration, volume){ - if (this.buffer){ - //default args - startTime = this.defaultArg(startTime, this.now()); - loopStart = this.defaultArg(loopStart, 0); - loopEnd = this.defaultArg(loopEnd, this.buffer.duration); - offset = this.defaultArg(offset, loopStart); - duration = this.defaultArg(duration, this.buffer.duration - offset); - //make/play the source - this.start(startTime, offset, duration, volume); - this.source.loop = true; - this.source.loopStart = this.toSeconds(loopStart); - this.source.loopEnd = this.toSeconds(loopEnd); - } - } - - //stop playback - Tone.Player.prototype.stop = function(stopTime){ - if (this.buffer && this.source){ - stopTime = this.defaultArg(stopTime, this.now()); - this.source.stop(this.toSeconds(stopTime)); - } - } - - //@returns {number} the buffer duration - Tone.Player.prototype.getDuration = function(){ - if (this.buffer){ - this.buffer.duration; - } else { - return 0; - } - } - - //@param {function(Event)} callback - Tone.Player.prototype._onended = function(e){ - this.onended(e); - } - - return Tone.Player; -}); - -/////////////////////////////////////////////////////////////////////////////// -// -// SAMPLE PLAYER -// -// dependencies : Tone, Player, Envelope, LFO -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/instrument/Sampler',["Tone/core/Tone", "Tone/component/Envelope", "Tone/source/Player"], function(Tone){ - - Tone.Sampler = function(url){ - Tone.call(this); - - //components - this.player = new Tone.Player(url); - this.envelope = new Tone.Envelope(.1, .01, .1, 1); - this.filter = this.context.createBiquadFilter(); - this.filter.type = "lowpass"; - this.filter.Q.value = 12; - this.filterEnvelope = new Tone.Envelope(.4, 0, 1, .6, this.filter.frequency, 0, 1200); - - //connect it up - this.chain(this.player, this.envelope, this.filter, this.output); - } - - Tone.extend(Tone.Sampler, Tone); - - - //@param {function()=} callback - Tone.Sampler.prototype.load = function(callback){ - this.player.load(callback); - } - - Tone.Sampler.prototype.triggerAttack = function(startTime){ - this.player.start(startTime); - this.envelope.triggerAttack(startTime); - this.filterEnvelope.triggerAttack(startTime); - } - - Tone.Sampler.prototype.triggerRelease = function(stopTime){ - stopTime = this.defaultArg(stopTime, this.now()); - this.player.stop(stopTime + Math.max(this.envelope.release, this.filterEnvelope.release)); - this.envelope.triggerRelease(stopTime); - this.filterEnvelope.triggerRelease(stopTime); - } - - return Tone.Sampler; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// BIT CRUSHER -// -// downsample incoming signal -// inspiration from https://github.com/jaz303/bitcrusher/blob/master/index.js -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/signal/BitCrusher',["Tone/core/Tone"], function(Tone){ - - //@param {number=} bits - //@param {number=} frequency - Tone.BitCrusher = function(bits, frequency){ - Tone.call(this); - - //the math - this.bits = this.defaultArg(bits, 8); - this.frequency = this.defaultArg(frequency, .5); - this.step = 2 * Math.pow(0.5, this.bits); - this.invStep = 1/this.step; - this.phasor = 0; - this.last = 0; - - //the node - this.crusher = this.context.createScriptProcessor(this.bufferSize, 1, 1); - this.crusher.onaudioprocess = this.audioprocess.bind(this); - - //connect it up - this.chain(this.input, this.crusher, this.output); - } - - Tone.extend(Tone.BitCrusher); - - Tone.BitCrusher.prototype.audioprocess = function(event){ - var bufferSize = this.crusher.bufferSize; - var phasor = this.phasor; - var freq = this.frequency; - var invStep = this.invStep; - var last = this.last; - var step = this.step; - var input = event.inputBuffer.getChannelData(0); - var output = event.outputBuffer.getChannelData(0); - for (var i = 0, len = output.length; i < len; i++) { - phasor += freq; - if (phasor >= 1) { - phasor -= 1; - last = step * ((input[i] * invStep) | 0 + 0.5); - } - output[i] = last; - } - this.phasor = phasor; - this.last = last; - } - - Tone.BitCrusher.prototype.setBits = function(bits){ - this.bits = bits; - this.step = 2 * Math.pow(0.5, this.bits); - this.invStep = 1/this.step; - } - - Tone.BitCrusher.prototype.setFrequency = function(freq){ - this.frequency = freq; - } - - return Tone.BitCrusher; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// SPLIT -// -// splits the incoming signal into left and right outputs -// one input two outputs -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/signal/Split',["Tone/core/Tone"], function(Tone){ - - Tone.Split = function(){ - Tone.call(this); - - //components - this.splitter = this.context.createChannelSplitter(2); - this.left = this.context.createGain(); - this.right = this.context.createGain(); - - //connections - this.input.connect(this.splitter); - this.splitter.connect(this.left, 1, 0); - this.splitter.connect(this.right, 0, 0); - } - - Tone.extend(Tone.Split); - - return Tone.Split; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// WEB RTC MICROPHONE -// -/////////////////////////////////////////////////////////////////////////////// - -define('Tone/source/Microphone',["Tone/core/Tone"], function(Tone){ - - //@param {number=} inputNum - Tone.Microphone = function(inputNum){ - //extend the base class - Tone.call(this); - - //components - this.mediaStream = null; - this.stream = null; - this.constraints = {"audio" : true}; - //get that option - var self = this; - MediaStreamTrack.getSources(function (media_sources) { - if (inputNum < media_sources.length){ - self.constraints.audio = { - optional : [{ sourceId: media_sources[inputNum].id}] - } - } - }); - } - - Tone.extend(Tone.Microphone, Tone); - - //stop the WebRTC connection - Tone.Microphone.prototype.start = function(){ - // Only get the audio stream. - navigator.getUserMedia(this.constraints, this._onStream.bind(this), this._onStreamError.bind(this)); - } - - //stop the WebRTC connection - Tone.Microphone.prototype.stop = function(){ - if (this.stream){ - this.stream.stop(); - } - } - - //when the stream is setup - Tone.Microphone.prototype._onStream = function(stream) { - this.stream = stream; - // Wrap a MediaStreamSourceNode around the live input stream. - this.mediaStream = this.context.createMediaStreamSource(stream); - this.mediaStream.connect(this.output); - }; - - //on error - Tone.Microphone.prototype._onStreamError = function(e) { - console.error(e); - }; - - //polyfill - navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia - || navigator.mozGetUserMedia || navigator.msGetUserMedia; - - return Tone.Microphone; -}); -/////////////////////////////////////////////////////////////////////////////// -// -// NOISE -// -/////////////////////////////////////////////////////////////////////////////// -define('Tone/source/Noise',["Tone/core/Tone"], function(Tone){ - - //@param {string} type the noise type - Tone.Noise = function(type){ - //extend Unit - Tone.call(this); - - //components - this.jsNode = this.context.createScriptProcessor(this.bufferSize, 0, 1); - - //connections - this.jsNode.connect(this.output); - - this.setType(this.defaultArg(type, "white")); - } - - Tone.extend(Tone.Noise, Tone); - - //@param {string} type ('white', 'pink', 'brown') - Tone.Noise.prototype.setType = function(type){ - switch (type){ - case "white" : - this.jsNode.onaudioprocess = this._whiteNoise.bind(this); - break; - case "pink" : - this.jsNode.onaudioprocess = this._pinkNoise.bind(this); - break; - case "brown" : - this.jsNode.onaudioprocess = this._brownNoise.bind(this); - break; - default : - this.jsNode.onaudioprocess = this._whiteNoise.bind(this); - } - } - - //modified from http://noisehack.com/generate-noise-web-audio-api/ - Tone.Noise.prototype._pinkNoise = (function() { - var b0, b1, b2, b3, b4, b5, b6; - b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0; - return function(e) { - var bufferSize = this.jsNode.bufferSize; - var output = e.outputBuffer.getChannelData(0); - for (var i = 0; i < bufferSize; 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; - output[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; - output[i] *= 0.11; // (roughly) compensate for gain - b6 = white * 0.115926; - } - } - })(); - - //modified from http://noisehack.com/generate-noise-web-audio-api/ - Tone.Noise.prototype._brownNoise = (function() { - var lastOut = 0.0; - return function(e) { - var bufferSize = this.jsNode.bufferSize; - var output = e.outputBuffer.getChannelData(0); - for (var i = 0; i < bufferSize; i++) { - var white = Math.random() * 2 - 1; - output[i] = (lastOut + (0.02 * white)) / 1.02; - lastOut = output[i]; - output[i] *= 3.5; // (roughly) compensate for gain - } - } - return node; - })(); - - //modified from http://noisehack.com/generate-noise-web-audio-api/ - Tone.Noise.prototype._whiteNoise = function(e){ - var bufferSize = this.jsNode.bufferSize; - var output = e.outputBuffer.getChannelData(0); - for (var i = 0; i < bufferSize; i++) { - output[i] = Math.random() * 2 - 1; - } - } - - return Tone.Noise; -}); diff --git a/build/package.json b/build/package.json new file mode 100644 index 00000000..6c9f04f0 --- /dev/null +++ b/build/package.json @@ -0,0 +1,19 @@ +{ + "name": "build", + "version": "0.0.0", + "description": "", + "main": "Gruntfile.js", + "directories": { + "doc": "doc" + }, + "dependencies": { + "grunt": "~0.4.5", + "grunt-jsdoc": "~0.5.4", + "grunt-contrib-clean": "~0.5.0", + "grunt-contrib-concat": "~0.4.0", + "grunt-contrib-requirejs": "~0.4.4" + }, + "devDependencies": {}, + "author": "", + "license": "ISC" +} diff --git a/doc/Tone.Add.html b/doc/Tone.Add.html new file mode 100644 index 00000000..6ac097fe --- /dev/null +++ b/doc/Tone.Add.html @@ -0,0 +1,1858 @@ + + + + + JSDoc: Class: Add + + + + + + + + + + +
+ +

Class: Add

+ + + + + +
+ +
+

+ Add +

+ +
+ +
+
+ + + + +
+

new Add(value)

+ + +
+
+ + +
+ Adds a value to an incoming signal +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

<private> _value :Tone

+ + +
+
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

setValue(value)

+ + +
+
+ + +
+ set the constant +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.AutoPanner.html b/doc/Tone.AutoPanner.html new file mode 100644 index 00000000..66ae7506 --- /dev/null +++ b/doc/Tone.AutoPanner.html @@ -0,0 +1,835 @@ + + + + + JSDoc: Class: AutoPanner + + + + + + + + + + +
+ +

Class: AutoPanner

+ + + + + +
+ +
+

+ AutoPanner +

+ +
+ +
+
+ + + + +
+

new AutoPanner(rate, amount)

+ + +
+
+ + +
+ AutoPanner creates a left-right panner effect (not a 3D panner). +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
rate + + +number + + + + + + <optional>
+ + + + + +
(optional) rate in HZ of the left-right pan
amount + + +number + + + + + + <optional>
+ + + + + +
(optional) of the pan in dB (0 - 1)
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + + + + + + + + + + + + + +

Methods

+ +
+ +
+

setAmount(amount)

+ + +
+
+ + +
+ Set the amount of the AutoPanner. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
amount + + +number + + + + in dB (0 - 1)
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setFrequency(rate)

+ + +
+
+ + +
+ Set frequency of the oscillator attached to the AutoPanner. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
rate + + +number +| + +string + + + + in HZ of the oscillator's frequency.
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setType(type)

+ + +
+
+ + +
+ Set the type of oscillator attached to the AutoPanner. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
type + + +string + + + + of oscillator the panner is attached to (sine|sawtooth|triangle|square)
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

start(Time)

+ + +
+
+ + +
+ Start the panner +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Time + + +Tone.Time + + + + the panner begins.
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

stop(time)

+ + +
+
+ + +
+ Stop the panner +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + + the panner stops.
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.BitCrusher.html b/doc/Tone.BitCrusher.html new file mode 100644 index 00000000..456655a6 --- /dev/null +++ b/doc/Tone.BitCrusher.html @@ -0,0 +1,2494 @@ + + + + + JSDoc: Class: BitCrusher + + + + + + + + + + +
+ +

Class: BitCrusher

+ + + + + +
+ +
+

+ BitCrusher +

+ +
+ +
+
+ + + + +
+

new BitCrusher(bits, frequency)

+ + +
+
+ + +
+ downsample incoming signal + inspiration from https://github.com/jaz303/bitcrusher/blob/master/index.js +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
bits + + +number + + + + + + <optional>
+ + + + + +
frequency + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

<private> _bits :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _crusher :ScriptProcessorNode

+ + +
+
+ + + +
Type:
+
    +
  • + +ScriptProcessorNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _frequency :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _invStep :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _last :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _phasor :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _step :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

<private> _audioprocess(event)

+ + +
+
+ + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +AudioProcessingEvent + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

setBits(bits)

+ + +
+
+ + +
+ set the bit rate +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bits + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setFrequency(freq)

+ + +
+
+ + +
+ set the frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
freq + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.DryWet.html b/doc/Tone.DryWet.html new file mode 100644 index 00000000..0b065931 --- /dev/null +++ b/doc/Tone.DryWet.html @@ -0,0 +1,486 @@ + + + + + JSDoc: Class: DryWet + + + + + + + + + + +
+ +

Class: DryWet

+ + + + + +
+ +
+

+ DryWet +

+ +
+ +
+
+ + + + +
+

new DryWet(initialDry)

+ + +
+
+ + +
+ DRY/WET KNOB + +equal power fading control values: + 0 = 100% dry + 1 = 100% wet +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
initialDry + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + + + + + + + + + + + + + +

Methods

+ +
+ +
+

setDry(val, rampTime)

+ + +
+
+ + +
+ Set the dry value of the knob +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
val + + +number + + + +
rampTime + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setWet(val, rampTime)

+ + +
+
+ + +
+ Set the wet value of the knob +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
val + + +number + + + +
rampTime + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Envelope.html b/doc/Tone.Envelope.html new file mode 100644 index 00000000..d5db1805 --- /dev/null +++ b/doc/Tone.Envelope.html @@ -0,0 +1,2501 @@ + + + + + JSDoc: Class: Envelope + + + + + + + + + + +
+ +

Class: Envelope

+ + + + + +
+ +
+

+ Envelope +

+ +
+ +
+
+ + + + +
+

new Envelope(attack, decay, sustain, release, minOutput, maxOutput)

+ + +
+
+ + +
+ Envelope + ADR envelope generator attaches to an AudioParam +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
attack + + +Tone.Time + + + + + + <optional>
+ + + + + +
decay + + +Tone.Time + + + + + + <optional>
+ + + + + +
sustain + + +number + + + + + + <optional>
+ + + + + +
a percentage (0-1) of the full amplitude
release + + +Tone.Time + + + + + + <optional>
+ + + + + +
minOutput + + +number + + + + + + <optional>
+ + + + + +
the lowest point of the envelope
maxOutput + + +number + + + + + + <optional>
+ + + + + +
the highest point of the envelope
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

<private> _connect

+ + +
+
+ +
+ pointer to the parent's connect method +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

connect(param)

+ + +
+
+ + +
+ connect the envelope + +if the envelope is connected to a param, the params +value will be set to 0 so that it doesn't interfere with the envelope +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
param + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

triggerAttack(time)

+ + +
+
+ + +
+ attack->decay->sustain linear ramp +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

triggerAttackExp(time)

+ + +
+
+ + +
+ attack->decay->sustain exponential ramp +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

triggerRelease(time)

+ + +
+
+ + +
+ triggers the release of the envelope with a linear ramp +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

triggerReleaseExp(time)

+ + +
+
+ + +
+ triggers the release of the envelope with an exponential ramp +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.LFO.html b/doc/Tone.LFO.html new file mode 100644 index 00000000..2545c6e9 --- /dev/null +++ b/doc/Tone.LFO.html @@ -0,0 +1,2900 @@ + + + + + JSDoc: Class: LFO + + + + + + + + + + +
+ +

Class: LFO

+ + + + + +
+ +
+

+ LFO +

+ +
+ +
+
+ + + + +
+

new LFO(rate, outputMin, outputMax)

+ + +
+
+ + +
+ Low Frequency Oscillator + + LFO produces an output signal which can be attached to an AudioParam + for constant control over that parameter + the LFO can also be synced to the transport +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
rate + + +number + + + + + + + + + +
outputMin + + +number + + + + + + <optional>
+ + + + + +
outputMax + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

<private> _connect

+ + +
+
+ +
+ pointer to the parent's connect method +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

oscillator :Tone.Oscillator

+ + +
+
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

scaler :Tone.Scale

+ + +
+
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

connect(param)

+ + +
+
+ + +
+ override the connect method so that it 0's out the value + if attached to an AudioParam +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
param + + +AudioNode +| + +AudioParam +| + +Tone + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

setFrequency(rate)

+ + +
+
+ + +
+ set the frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
rate + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setMax(min)

+ + +
+
+ + +
+ set the maximum output of the LFO +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
min + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setMin(min)

+ + +
+
+ + +
+ set the minimum output of the LFO +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
min + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setType(type)

+ + +
+
+ + +
+ set the waveform of the LFO +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
type + + +string + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

start(time)

+ + +
+
+ + +
+ start the LFO +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

stop(time)

+ + +
+
+ + +
+ stop the LFO +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

sync()

+ + +
+
+ + +
+ Sync the start/stop/pause to the transport + and the frequency to the bpm of the transport +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

unsync()

+ + +
+
+ + +
+ unsync the LFO from transport control +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Merge.html b/doc/Tone.Merge.html new file mode 100644 index 00000000..4d047b6e --- /dev/null +++ b/doc/Tone.Merge.html @@ -0,0 +1,1830 @@ + + + + + JSDoc: Class: Merge + + + + + + + + + + +
+ +

Class: Merge

+ + + + + +
+ +
+

+ Merge +

+ +
+ +
+
+ + + + +
+

new Merge()

+ + +
+
+ + +
+ merge a left and a right channel into a single stereo channel + + instead of connecting to the input, connect to either the left, or right input + + default input for connect is left input +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

left :GainNode

+ + +
+
+ +
+ the left input channel + also an alias for the input +
+ + + +
Type:
+
    +
  • + +GainNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

merger :ChannelMergerNode

+ + +
+
+ +
+ the merger node for the two channels +
+ + + +
Type:
+
    +
  • + +ChannelMergerNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+ + + +
+
+ +
+ the right input channel +
+ + + +
Type:
+
    +
  • + +GainNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Meter.html b/doc/Tone.Meter.html new file mode 100644 index 00000000..a24f4dfa --- /dev/null +++ b/doc/Tone.Meter.html @@ -0,0 +1,2758 @@ + + + + + JSDoc: Class: Meter + + + + + + + + + + +
+ +

Class: Meter

+ + + + + +
+ +
+

+ Meter +

+ +
+ +
+
+ + + + +
+

new Meter(channels, smoothing, clipMemory)

+ + +
+
+ + +
+ get the rms of the input signal with some averaging + can also just get the value of the signal + or the value in dB + + inspired by https://github.com/cwilso/volume-meter/blob/master/volume-meter.js + The MIT License (MIT) Copyright (c) 2014 Chris Wilson +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
channels + + +number + + + + + + <optional>
+ + + + + +
(optional) number of channels being metered
smoothing + + +number + + + + + + <optional>
+ + + + + +
(optional) amount of smoothing applied to the volume
clipMemory + + +number + + + + + + <optional>
+ + + + + +
(optional) number in ms that a "clip" should be remembered
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

<private> _jsNode :ScriptProcessorNode

+ + +
+
+ + + +
Type:
+
    +
  • + +ScriptProcessorNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _lastClip :number

+ + +
+
+ +
+ last time the values clipped +
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _values :Array.<number>

+ + +
+
+ +
+ the raw values for each of the channels +
+ + + +
Type:
+
    +
  • + +Array.<number> + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _volume :Array.<number>

+ + +
+
+ +
+ the rms for each of the channels +
+ + + +
Type:
+
    +
  • + +Array.<number> + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

channels :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

clipMemory :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

smoothing :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

<private> _onprocess(event)

+ + +
+
+ + +
+ called on each processing frame +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +AudioProcessingEvent + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

getDb(channel) → {number}

+ + +
+
+ + +
+ get the volume of the signal in dB +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
channel + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

getLevel(channel) → {number}

+ + +
+
+ + +
+ get the rms of the signal +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
channel + + +number + + + + + + <optional>
+ + + + + +
which channel
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the value +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

getValue(channel) → {number}

+ + +
+
+ + +
+ get the value of the signal +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
channel + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Multiply.html b/doc/Tone.Multiply.html new file mode 100644 index 00000000..53e8676f --- /dev/null +++ b/doc/Tone.Multiply.html @@ -0,0 +1,1875 @@ + + + + + JSDoc: Class: Multiply + + + + + + + + + + +
+ +

Class: Multiply

+ + + + + +
+ +
+

+ Multiply +

+ +
+ +
+
+ + + + +
+

new Multiply(value)

+ + +
+
+ + +
+ Multiply the incoming signal by some factor +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
value + + +number + + + + + + <optional>
+ + + + + +
constant value to multiple
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

input :GainNode

+ + +
+
+ +
+ the input node is the same as the output node + it is also the GainNode which handles the scaling of incoming signal +
+ + + +
Type:
+
    +
  • + +GainNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

setValue(value)

+ + +
+
+ + +
+ set the constant multiple +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Oscillator.html b/doc/Tone.Oscillator.html new file mode 100644 index 00000000..141e17ad --- /dev/null +++ b/doc/Tone.Oscillator.html @@ -0,0 +1,2970 @@ + + + + + JSDoc: Class: Oscillator + + + + + + + + + + +
+ +

Class: Oscillator

+ + + + + +
+ +
+

+ Oscillator +

+ +
+ +
+
+ + + + +
+

new Oscillator(freq, type)

+ + +
+
+ + +
+ Oscillator + + Oscilator with start, pause, stop and sync to Transport +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
freq + + +number +| + +string + + + + + + + + + + starting frequency
type + + +string + + + + + + <optional>
+ + + + + +
type of oscillator (sine|square|triangle|sawtooth)
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

frequency :Tone.Signal

+ + +
+
+ +
+ the frequency control signal +
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

oscillator :OscillatorNode

+ + +
+
+ +
+ the main oscillator +
+ + + +
Type:
+
    +
  • + +OscillatorNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

output :GainNode

+ + +
+
+ +
+ unlike most ToneNodes, Sources only have an output and no input +
+ + + +
Type:
+
    +
  • + +GainNode + + +
  • +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

fadeTo(value, time)

+ + +
+
+ + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
time + + +Tone.Time + + + + (relative to 'now')
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

<abstract> pause(time)

+ + +
+
+ + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

setFrequency(val, rampTime)

+ + +
+
+ + +
+ exponentially ramp the frequency of the oscillator over the rampTime +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
val + + +Tone.Time + + + + + + + + + +
rampTime + + +Tone.Time + + + + + + <optional>
+ + + + + +
when the oscillator will arrive at the frequency
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setType(type)

+ + +
+
+ + +
+ set the oscillator type +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
type + + +string + + + + (sine|square|triangle|sawtooth)
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setVolume(value)

+ + +
+
+ + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

start(time)

+ + +
+
+ + +
+ start the oscillator +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

stop(time)

+ + +
+
+ + +
+ stop the oscillator +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + <optional>
+ + + + + +
(optional) timing parameter
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

sync()

+ + +
+
+ + +
+ Sync the oscillator to the transport + + the current ratio between the oscillator and the Transport BPM + is fixed and any change to the Transport BPM will change this + oscillator in that same ratio + + Transport start/pause/stop will also start/pause/stop the oscillator +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

unsync()

+ + +
+
+ + +
+ unsync the oscillator from the Transport +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Recorder.html b/doc/Tone.Recorder.html new file mode 100644 index 00000000..b273db35 --- /dev/null +++ b/doc/Tone.Recorder.html @@ -0,0 +1,2489 @@ + + + + + JSDoc: Class: Recorder + + + + + + + + + + +
+ +

Class: Recorder

+ + + + + +
+ +
+

+ Recorder +

+ +
+ +
+
+ + + + +
+

new Recorder(channels)

+ + +
+
+ + +
+ Record an input into an array or AudioBuffer + + it is limited in that the recording length needs to be known beforehand +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channels + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

<private> _jsNode :ScriptProcessorNode

+ + +
+
+ + + +
Type:
+
    +
  • + +ScriptProcessorNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _recordBufferOffset :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _recordBuffers :Array.<Float32Array>

+ + +
+
+ +
+ Float32Array for each channel +
+ + + +
Type:
+
    +
  • + +Array.<Float32Array> + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

channels :number

+ + +
+
+ +
+ the number of channels in the recording +
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

<private> _audioprocess(event)

+ + +
+
+ + +
+ internal method called on audio process +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +AudioProcessorEvent + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

clear()

+ + +
+
+ + +
+ clears the recording buffer +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

getAudioBuffer() → {AudioBuffer}

+ + +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +AudioBuffer + + +
+
+ + + + +
+ + + +
+

getFloat32Array() → {Array.<Float32Array>}

+ + +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Array.<Float32Array> + + +
+
+ + + + +
+ + + +
+

isEmpty() → {boolean}

+ + +
+
+ + +
+ true if there is nothing in the buffers +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + +
+ + + +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

record(time)

+ + +
+
+ + +
+ Record for a certain period of time + + will clear the internal buffer before starting +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Scale.html b/doc/Tone.Scale.html new file mode 100644 index 00000000..30a22fc2 --- /dev/null +++ b/doc/Tone.Scale.html @@ -0,0 +1,2750 @@ + + + + + JSDoc: Class: Scale + + + + + + + + + + +
+ +

Class: Scale

+ + + + + +
+ +
+

+ Scale +

+ +
+ +
+
+ + + + +
+

new Scale(inputMin, inputMax, outputMin, outputMax)

+ + +
+
+ + +
+ performs a linear scaling on an input signal + + scales from the input range of inputMin to inputMax + to the output range of outputMin to outputMax + + if only two arguments are provided, the inputMin and inputMax are set to -1 and 1 +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
inputMin + + +number + + + + + + + + + +
inputMax + + +number + + + + + + + + + +
outputMin + + +number + + + + + + <optional>
+ + + + + +
outputMax + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

<private> _inputMax :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _inputMin :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _outputMax :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _outputMin :number

+ + +
+
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _plusInput :Tone.Add

+ + +
+
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _plusOutput :Tone.Add

+ + +
+
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<private> _scale :Tone.Multiply

+ + +
+
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

<private> _setScalingParameters()

+ + +
+
+ + +
+ set the scaling parameters +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

setInputMax(val)

+ + +
+
+ + +
+ set the input max value +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
val + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setInputMin(val)

+ + +
+
+ + +
+ set the input min value +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
val + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setOutputMax(val)

+ + +
+
+ + +
+ set the output max value +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
val + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setOutputMin(val)

+ + +
+
+ + +
+ set the output min value +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
val + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:22 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Signal.html b/doc/Tone.Signal.html new file mode 100644 index 00000000..c7b9a08c --- /dev/null +++ b/doc/Tone.Signal.html @@ -0,0 +1,2055 @@ + + + + + JSDoc: Class: Signal + + + + + + + + + + +
+ +

Class: Signal

+ + + + + +
+ +
+

+ Signal +

+ +
+ +
+
+ + + + +
+

new Signal(value)

+ + +
+
+ + +
+ constant audio-rate signal + + Tone.Signal is a core component which allows for synchronization of many components. + A single signal can drive multiple parameters by applying Scaling. + + For example: to synchronize two Tone.Oscillators in octaves of each other, + Signal --> OscillatorA.frequency + ^--> Tone.Multiply(2) --> OscillatorB.frequency + + + Tone.Signal can be scheduled with all of the functions available to AudioParams +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
value + + +number + + + + + + <optional>
+ + + + + +
(optional) initial value
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + + + + + + + + + + + +

Members

+ +
+ +
+

<private> _syncRatio :number

+ + +
+
+ +
+ the ratio of the this value to the control signal value +
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

output :GainNode

+ + +
+
+ +
+ the output node +
+ + + +
Type:
+
    +
  • + +GainNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

scalar :GainNode

+ + +
+
+ +
+ scales the constant output to the desired output +
+ + + +
Type:
+
    +
  • + +GainNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

cancelScheduledValues(startTime)

+ + +
+
+ + +
+ Cancels all scheduled parameter changes with times greater than or + equal to startTime. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
startTime + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

exponentialRampToValueAtTime(value, endTime)

+ + +
+
+ + +
+ Schedules an exponential continuous change in parameter value from + the previous scheduled parameter value to the given value. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
endTime + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

exponentialRampToValueNow(value, endTime)

+ + +
+
+ + +
+ Schedules an exponential continuous change in parameter value from + the current time and current value to the given value. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
endTime + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

getValue() → {number}

+ + +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the current value of the signal +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

linearRampToValueAtTime(value, endTime)

+ + +
+
+ + +
+ Schedules a linear continuous change in parameter value from the + previous scheduled parameter value to the given value. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
endTime + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

linearRampToValueNow(value, endTime)

+ + +
+
+ + +
+ Schedules an linear continuous change in parameter value from + the current time and current value to the given value at the given time. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
endTime + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setCurrentValueNow() → {number}

+ + +
+
+ + +
+ creates a schedule point with the current value at the current time +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the current value +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

setTargetAtTime(value, startTime, timeConstant)

+ + +
+
+ + +
+ Start exponentially approaching the target value at the given time with + a rate having the given time constant. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
startTime + + +Tone.Time + + + +
timeConstant + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setValue(value)

+ + +
+
+ + +
+ set the value of the signal right away + will be overwritten if there are previously scheduled automation curves +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setValueAtTime(value, time)

+ + +
+
+ + +
+ Schedules a parameter value change at the given time. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setValueCurveAtTime(values, startTime, duration)

+ + +
+
+ + +
+ Sets an array of arbitrary parameter values starting at the given time + for the given duration. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
values + + +Array.<number> + + + +
startTime + + +Tone.Time + + + +
duration + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

sync(signal)

+ + +
+
+ + +
+ Sync this to another signal and it will always maintain the + ratio between the two signals until it is unsynced +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
signal + + +Tone.Signal + + + + to sync to
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

unsync()

+ + +
+
+ + +
+ unbind the signal control + + will leave the signal value as it was without the influence of the control signal +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:22 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Source.html b/doc/Tone.Source.html new file mode 100644 index 00000000..e1f5f5be --- /dev/null +++ b/doc/Tone.Source.html @@ -0,0 +1,2285 @@ + + + + + JSDoc: Class: Source + + + + + + + + + + +
+ +

Class: Source

+ + + + + +
+ +
+

+ Source +

+ +
+ +
+
+ + + + +
+

new Source()

+ + +
+
+ + +
+ base class for sources +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

output :GainNode

+ + +
+
+ +
+ unlike most ToneNodes, Sources only have an output and no input +
+ + + +
Type:
+
    +
  • + +GainNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

fadeTo(value, time)

+ + +
+
+ + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
time + + +Tone.Time + + + + (relative to 'now')
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

<abstract> pause(time)

+ + +
+
+ + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

setVolume(value)

+ + +
+
+ + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

<abstract> start(time)

+ + +
+
+ + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

<abstract> stop(time)

+ + +
+
+ + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:22 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Split.html b/doc/Tone.Split.html new file mode 100644 index 00000000..55724167 --- /dev/null +++ b/doc/Tone.Split.html @@ -0,0 +1,1759 @@ + + + + + JSDoc: Class: Split + + + + + + + + + + +
+ +

Class: Split

+ + + + + +
+ +
+

+ Split +

+ +
+ +
+
+ + + + +
+

new Split()

+ + +
+
+ + +
+ split the incoming signal into left and right channels + + the left channel is the default output +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + +

Extends

+ + + + + + + + + + + + + +

Members

+ +
+ +
+

isFrequency

+ + +
+
+ +
+ true if the input is in the format number+hz + i.e.: 10hz +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isNotation

+ + +
+
+ +
+ tests if a string is musical notation + i.e.: + 4n = quarter note + 2m = two measures + 8t = eighth-note triplet +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

isTransportTime

+ + +
+
+ +
+ tests if a string is transportTime + i.e. : + 1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes +
+ + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+ + + +
+
+ +
+ the right channel output +
+ + + +
Type:
+
    +
  • + +GainNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

splitter :ChannelSplitterNode

+ + +
+
+ + + +
Type:
+
    +
  • + +ChannelSplitterNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

notationToSeconds(notation, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert notation format strings to seconds +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
notation + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

receive(channelName)

+ + +
+
+ + +
+ recieve the input from the desired channelName to the input gain of 'this' node. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

send(channelName, amount) → {GainNode}

+ + +
+
+ + +
+ send signal to a channel name +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
channelName + + +string + + + +
amount + + +number + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +GainNode + + +
+
+ + + + +
+ + + +
+

toFrequency(time) → {number}

+ + +
+
+ + +
+ convert a time to a frequency +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the time in hertz +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

toSeconds(time, bpm, timeSignature)

+ + +
+
+ + +
+ convert Tone.Time into seconds + + unlike the method which it overrides, this takes into account + transporttime and musical notation +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
time + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTransportTime(seconds, bpm, timeSignature) → {string}

+ + +
+
+ + +
+ Convert seconds to the closest transportTime in the form + measures:quarters:sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
seconds + + +Tone.Time + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

transportTimeToSeconds(transportTime, bpm, timeSignature) → {number}

+ + +
+
+ + +
+ convert transportTime into seconds + i.e.: + 4:2:3 == 4 measures + 2 quarters + 3 sixteenths +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
transportTime + + +string + + + + + + + + + +
bpm + + +number + + + + + + <optional>
+ + + + + +
timeSignature + + +number + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ seconds +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:22 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.Transport.html b/doc/Tone.Transport.html new file mode 100644 index 00000000..61ef5faa --- /dev/null +++ b/doc/Tone.Transport.html @@ -0,0 +1,3063 @@ + + + + + JSDoc: Class: Transport + + + + + + + + + + +
+ +

Class: Transport

+ + + + + +
+ +
+

+ Transport +

+ +
+ +
+
+ + + + +
+

new Transport()

+ + +
+
+ + +
+ oscillator-based transport allows for simple musical timing + supports tempo curves and time changes +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + +
+ + + + + + + + + + + + +

Members

+ +
+ +
+

<private> _jsNode :ScriptProcessorNode

+ + +
+
+ +
+ watches the main oscillator for timing ticks +
+ + + +
Type:
+
    +
  • + +ScriptProcessorNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

loop :boolean

+ + +
+
+ + + +
Type:
+
    +
  • + +boolean + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

_processBuffer(event)

+ + +
+
+ + +
+ called when a buffer is ready +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +AudioProcessingEvent + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

clearInterval(rmInterval) → {boolean}

+ + +
+
+ + +
+ clear an interval from the processing array +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
rmInterval + + +number + + + + the interval to remove
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ true if the event was removed +
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + +
+ + + +
+

clearTimeline(timelineID) → {boolean}

+ + +
+
+ + +
+ clear the timeline event from the +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
timelineID + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ true if it was removed +
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + +
+ + + +
+

clearTimeout(timeoutID) → {boolean}

+ + +
+
+ + +
+ clear the timeout based on it's ID +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
timeoutID + + +number + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ true if the timeout was removed +
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + +
+ + + +
+

getBpm() → {number}

+ + +
+
+ + +
+ return the current BPM +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

getTimeSignature() → {number}

+ + +
+
+ + +
+ return the time signature as just the numerator + over 4 is assumed. + for example 4/4 would return 4 and 6/8 would return 3 +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

getTransportTime() → {string}

+ + +
+
+ + +
+ get the transport time +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ in transportTime format (measures:beats:sixteenths) +
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

pause(time)

+ + +
+
+ + +
+ pause the transport and all sources synced to the transport +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setBpm(bpm, rampTime)

+ + +
+
+ + +
+ set the BPM + optionally ramp to the bpm over some time +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
bpm + + +number + + + + + + + + + +
rampTime + + +Tone.Time + + + + + + <optional>
+ + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setInterval(callback, interval, ctx) → {number}

+ + +
+
+ + +
+ intervals are recurring events +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
callback + + +function + + + +
interval + + +Tone.Time + + + +
ctx + + +Object + + + + the context the function is invoked in
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the id of the interval +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

setLoopEnd(endPosition)

+ + +
+
+ + +
+ set the loop start position +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
endPosition + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setLoopPoint(startPosition, endPosition)

+ + +
+
+ + +
+ shorthand loop setting +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
startPosition + + +Tone.Time + + + +
endPosition + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setLoopStart(startPosition)

+ + +
+
+ + +
+ set the loop start position +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
startPosition + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

setTimeline(callback, timeout, ctx) → {number}

+ + +
+
+ + +
+ Timeline events are synced to the timeline of the Transport + Unlike Timeout, Timeline events will restart after the + Transport has been stopped and restarted. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
callback + + +function + + + +
timeout + + +Tome.Time + + + +
ctx + + +Object + + + + the context in which the funtion is called
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the id for clearing the timeline event +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

setTimeout(callback, time, ctx) → {number}

+ + +
+
+ + +
+ set a timeout to occur after time from now +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
callback + + +function + + + +
time + + +Tone.Time + + + +
ctx + + +Object + + + + the context to invoke the callback in
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ the id of the timeout for clearing timeouts +
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

setTimeSignature(numerator, denominator)

+ + +
+
+ + +
+ set the time signature +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
numerator + + +number + + + + + + + + + +
denominator + + +number + + + + + + <optional>
+ + + + + +
defaults to 4
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Example
+ +
 this.setTimeSignature(4); //for 4/4
+ 
+ 
+ + +
+ + + +
+

setTransportTime(progress)

+ + +
+
+ + +
+ set the transport time, jump to the position right away +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
progress + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

start(time)

+ + +
+
+ + +
+ start the transport and all sources synced to the transport +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

stop(time)

+ + +
+
+ + +
+ stop the transport and all sources synced to the transport +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

toTicks(time) → {number}

+ + +
+
+ + +
+ turns the time into +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
time + + +Tone.Time + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +number + + +
+
+ + + + +
+ + + +
+

unsync(source)

+ + +
+
+ + +
+ remove the source from the list of Synced Sources +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
source + + +Tone.Source + + + + [description]
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:22 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/Tone.js.html b/doc/Tone.js.html new file mode 100644 index 00000000..ce878241 --- /dev/null +++ b/doc/Tone.js.html @@ -0,0 +1,3340 @@ + + + + + JSDoc: Source: Tone.js + + + + + + + + + + +
+ +

Source: Tone.js

+ + + + + +
+
+
///////////////////////////////////////////////////////////////////////////////
+//
+//	TONE.js
+//
+//	@author Yotam Mann
+//	
+//	The MIT License (MIT) 2014
+///////////////////////////////////////////////////////////////////////////////
+
+(function (root, factory) {
+	//can run with or without requirejs
+	if (typeof define === "function" && define.amd) {
+		// AMD. Register as an anonymous module.
+		define("Tone/core/Tone",[],function () {
+			var Tone = factory(root);
+			return Tone;
+		});
+	} else if (typeof root.Tone !== "function") {
+		//make Tone public
+		root.Tone = factory(root);
+		//define 'define' to invoke the callbacks with Tone
+		root.define = function(name, deps, func){
+			func(root.Tone);
+		};
+	}
+} (this, function (global) {
+
+	//////////////////////////////////////////////////////////////////////////
+	//	WEB AUDIO CONTEXT
+	///////////////////////////////////////////////////////////////////////////
+
+	//ALIAS
+	if (!global.AudioContext){
+		global.AudioContext = global.webkitAudioContext;
+	} 
+
+	var audioContext;
+	if (global.AudioContext){
+		audioContext = new global.AudioContext();
+	}
+
+	//SHIMS////////////////////////////////////////////////////////////////////
+
+	if (typeof audioContext.createGain !== "function"){
+		audioContext.createGain = audioContext.createGainNode;
+	}
+	if (typeof audioContext.createDelay !== "function"){
+		audioContext.createDelay = audioContext.createDelayNode;
+	}
+
+	if (typeof AudioBufferSourceNode.prototype.start !== "function"){
+		AudioBufferSourceNode.prototype.start = AudioBufferSourceNode.prototype.noteGrainOn;
+	}
+	if (typeof AudioBufferSourceNode.prototype.stop !== "function"){
+		AudioBufferSourceNode.prototype.stop = AudioBufferSourceNode.prototype.noteOff;
+	}
+	if (typeof OscillatorNode.prototype.start !== "function"){
+		OscillatorNode.prototype.start = OscillatorNode.prototype.noteOn;
+	}
+	if (typeof OscillatorNode.prototype.stop !== "function"){
+		OscillatorNode.prototype.stop = OscillatorNode.prototype.noteOff;	
+	}
+	//extend the connect function to include Tones
+	AudioNode.prototype._nativeConnect = AudioNode.prototype.connect;
+	AudioNode.prototype.connect = function(B){
+		if (B.input && B.input instanceof GainNode){
+			this._nativeConnect(B.input);
+		} else {
+			try {
+				this._nativeConnect.apply(this, arguments);
+			} catch (e) {
+				throw new Error("trying to connect to a node with no inputs");
+			}
+		}
+	};
+
+	///////////////////////////////////////////////////////////////////////////
+	//	TONE
+	//	@constructor
+	///////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  Tone is the baseclass of all ToneNodes
+	 *  From Tone, children inherit timing and math which is used throughout Tone.js
+	 *  
+	 *  @constructor
+	 */
+	var Tone = function(){
+		/**
+		 *  default input of the ToneNode
+		 *  
+		 *  @type {GainNode}
+		 */
+		this.input = audioContext.createGain();
+		/**
+		 *  default output of the ToneNode
+		 *  
+		 *  @type {GainNode}
+		 */
+		this.output = audioContext.createGain();
+	};
+
+	///////////////////////////////////////////////////////////////////////////
+	//	CLASS VARS
+	///////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  A pointer to the audio context
+	 *  @type {AudioContext}
+	 */
+	Tone.prototype.context = audioContext;
+
+	/**
+	 *  A static pointer to the audio context
+	 *  @type {AudioContext}
+	 */
+	Tone.context = audioContext;
+
+	/**
+	 *  the default buffer size
+	 *  @type {number}
+	 */
+	Tone.prototype.bufferSize = 2048;
+
+	/**
+	 *  the default resolution for WaveShaperNodes
+	 *  @type {number}
+	 */
+	Tone.prototype.waveShaperResolution = 1024;
+	
+	///////////////////////////////////////////////////////////////////////////
+	//	CONNECTIONS
+	///////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode
+	 *  @param  {Tone | AudioParam | AudioNode} unit 
+	 */
+	Tone.prototype.connect = function(unit){
+		this.output.connect(unit);
+	};
+
+	/**
+	 *  disconnect the output
+	 */
+	Tone.prototype.disconnect = function(){
+		this.output.disconnect();
+	};
+	
+	/**
+	 *  connect together all of the arguments in series
+	 *  @param {...AudioParam|Tone}
+	 */
+	Tone.prototype.chain = function(){
+		if (arguments.length > 1){
+			var currentUnit = arguments[0];
+			for (var i = 1; i < arguments.length; i++){
+				var toUnit = arguments[i];
+				currentUnit.connect(toUnit);
+				currentUnit = toUnit;
+			}
+		}
+	};
+
+	///////////////////////////////////////////////////////////////////////////
+	//	UTILITIES / HELPERS / MATHS
+	///////////////////////////////////////////////////////////////////////////
+
+	//borrowed from underscore.js
+	function isUndef(val){
+		return val === void 0;
+	}
+
+	/**
+	 *  if a the given is undefined, use the fallback
+	 *  
+	 *  @param  {*} given    
+	 *  @param  {*} fallback 
+	 *  @return {*}          
+	 */
+	Tone.prototype.defaultArg = function(given, fallback){
+		return isUndef(given) ? fallback : given;
+	};
+
+	/**
+	 *  equal power gain scale
+	 *  good for cross-fading
+	 *  	
+	 *  @param  {number} percent (0-1)
+	 *  @return {number}         output gain (0-1)
+	 */
+	Tone.prototype.equalPowerScale = function(percent){
+		var piFactor = 0.5 * Math.PI;
+		return Math.sin(percent * piFactor);
+	};
+
+	/**
+	 *  @param  {number} gain (0-1)
+	 *  @return {number}      gain (decibel scale but betwee 0-1)
+	 */
+	Tone.prototype.logScale = function(gain) {
+		return  Math.max(this.normalize(this.gainToDb(gain), -100, 0), 0);
+	};
+
+	/**
+	 *  @param  {number} gain (0-1)
+	 *  @return {number}      gain (decibel scale but betwee 0-1)
+	 */
+	Tone.prototype.expScale = function(gain) {
+		return this.dbToGain(this.interpolate(gain, -100, 0));
+	};
+
+	/**
+	 *  convert db scale to gain scale (0-1)
+	 *  @param  {number} db
+	 *  @return {number}   
+	 */
+	Tone.prototype.dbToGain = function(db) {
+		return Math.pow(2, db / 6);
+	};
+
+	/**
+	 *  convert gain scale to decibels
+	 *  @param  {number} gain (0-1)
+	 *  @return {number}   
+	 */
+	Tone.prototype.gainToDb = function(gain) {
+		return  20 * (Math.log(gain) / Math.LN10);
+	};
+
+	/**
+	 *  interpolate the input value (0-1) to be between outputMin and outputMax
+	 *  @param  {number} input     
+	 *  @param  {number} outputMin 
+	 *  @param  {number} outputMax 
+	 *  @return {number}           
+	 */
+	Tone.prototype.interpolate = function(input, outputMin, outputMax){
+		return input*(outputMax - outputMin) + outputMin;
+	};
+
+	/**
+	 *  normalize the input to 0-1 from between inputMin to inputMax
+	 *  @param  {number} input    
+	 *  @param  {number} inputMin 
+	 *  @param  {number} inputMax 
+	 *  @return {number}          
+	 */
+	Tone.prototype.normalize = function(input, inputMin, inputMax){
+		//make sure that min < max
+		if (inputMin > inputMax){
+			var tmp = inputMax;
+			inputMax = inputMin;
+			inputMin = tmp;
+		} else if (inputMin == inputMax){
+			return 0;
+		}
+		return (input - inputMin) / (inputMax - inputMin);
+	};
+
+
+	///////////////////////////////////////////////////////////////////////////
+	//	TIMING
+	///////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  @return {number} the currentTime from the AudioContext
+	 */
+	Tone.prototype.now = function(){
+		return audioContext.currentTime;
+	};
+
+	/**
+	 *  convert a sample count to seconds
+	 *  @param  {number} samples 
+	 *  @return {number}         
+	 */
+	Tone.prototype.samplesToSeconds = function(samples){
+		return samples / audioContext.sampleRate;
+	};
+
+	/**
+	 *  convert a time into samples
+	 *  
+	 *  @param  {Tone.time} time
+	 *  @return {number}         
+	 */
+	Tone.prototype.toSamples = function(time){
+		var seconds = this.toSeconds(time);
+		return seconds * audioContext.sampleRate;
+	};
+
+	/**
+	 *  convert Tone.Time to seconds
+	 *
+	 *  this is a simplified version which only handles numbers and 
+	 *  'now' relative numbers. If the Transport is included this 
+	 *  method is overridden to include many other features including 
+	 *  notationTime, Frequency, and transportTime
+	 *  
+	 *  @param  {Tone.Time} time 
+	 *  @return {number}     
+	 */
+	Tone.prototype.toSeconds = function(time){
+		if (typeof time === "number"){
+			return time; //assuming that it's seconds
+		} else if (typeof time === "string"){
+			var plusTime = 0;
+			if(time.charAt(0) === "+") {
+				plusTime = this.now();
+				time = time.slice(1);				
+			} 
+			return parseFloat(time) + plusTime;
+		} else {
+			return this.now();
+		}
+	};
+
+
+	/**
+	 *  convert a frequency into seconds
+	 *  accepts both numbers and strings 
+	 *  	i.e. 10hz or 10 both equal .1
+	 *  
+	 *  @param  {number|string} freq 
+	 *  @return {number}      
+	 */
+	Tone.prototype.frequencyToSeconds = function(freq){
+		return 1 / parseFloat(freq);
+	};
+
+	/**
+	 *  convert a number in seconds to a frequency
+	 *  @param  {number} seconds 
+	 *  @return {number}         
+	 */
+	Tone.prototype.secondsToFrequency = function(seconds){
+		return 1/seconds;
+	};
+
+	///////////////////////////////////////////////////////////////////////////
+	//	STATIC METHODS
+	///////////////////////////////////////////////////////////////////////////
+		
+	/**
+	 *  have a child inherit all of Tone's (or a parent's) prototype
+	 *  to inherit the parent's properties, make sure to call 
+	 *  Parent.call(this) in the child's constructor
+	 *
+	 *  based on closure library's inherit function
+	 *  
+	 *  @param  {function} 	child  
+	 *  @param  {function=} parent (optional) parent to inherit from
+	 *                             if no parent is supplied, the child
+	 *                             will inherit from Tone
+	 */
+	Tone.extend = function(child, parent){
+		if (isUndef(parent)){
+			parent = Tone;
+		}
+		function tempConstructor(){}
+		tempConstructor.prototype = parent.prototype;
+		child.prototype = new tempConstructor();
+		/** @override */
+		child.prototype.constructor = child;
+	};
+
+	return Tone;
+}));
+
+define('Tone/signal/Signal',["Tone/core/Tone"], function(Tone){
+
+	//all signals share a common constant signal generator
+	/**
+	 *  @static
+	 *  @private
+	 *  @type {OscillatorNode} 
+	 */
+	var generator = Tone.context.createOscillator();
+
+	/**
+	 *  @static
+	 *  @private
+	 *  @type {WaveShaperNode} 
+	 */
+	var constant = Tone.context.createWaveShaper();
+
+	//generate the waveshaper table which outputs 1 for any input value
+	(function(){
+		var len = 8;
+		var curve = new Float32Array(len);
+		for (var i = 0; i < len; i++){
+			//all inputs produce the output value
+			curve[i] = 1;
+		}
+		constant.curve = curve;
+	})();
+
+	generator.connect(constant);
+	generator.start(0);
+
+	/**
+	 *  constant audio-rate signal
+	 *
+	 *  Tone.Signal is a core component which allows for synchronization of many components. 
+	 *  A single signal can drive multiple parameters by applying Scaling. 
+	 *
+	 *  For example: to synchronize two Tone.Oscillators in octaves of each other, 
+	 *  	Signal --> OscillatorA.frequency
+	 *  		  ^--> Tone.Multiply(2) --> OscillatorB.frequency
+	 *  
+	 *
+	 *  Tone.Signal can be scheduled with all of the functions available to AudioParams
+	 *
+	 *
+	 *  @constructor
+	 *  @param {number=} value (optional) initial value
+	 */
+	Tone.Signal = function(value){
+		/**
+		 *  scales the constant output to the desired output
+		 *  @type {GainNode}
+		 */
+		this.scalar = this.context.createGain();
+		/**
+		 *  the output node
+		 *  @type {GainNode}
+		 */
+		this.output = this.context.createGain();
+		/**
+		 *  the ratio of the this value to the control signal value
+		 *
+		 *  @private
+		 *  @type {number}
+		 */
+		this._syncRatio = 1;
+
+		//connect the constant 1 output to the node output
+		this.chain(constant, this.scalar, this.output);
+
+		//set the default value
+		this.setValue(this.defaultArg(value, 0));
+
+	};
+
+	Tone.extend(Tone.Signal);
+
+	/**
+	 *  @return {number} the current value of the signal
+	 */
+	Tone.Signal.prototype.getValue = function(){
+		return this.scalar.gain.value;
+	};
+
+	/**
+	 *  set the value of the signal right away
+	 *  will be overwritten if there are previously scheduled automation curves
+	 *  
+	 *  @param {number} value 
+	 */
+	Tone.Signal.prototype.setValue = function(value){
+		if (this._syncRatio === 0){
+			value = 0;
+		} else {
+			value *= this._syncRatio;
+		}
+		this.scalar.gain.value = value;
+	};
+
+	/**
+	 *  Schedules a parameter value change at the given time.
+	 *  
+	 *  @param {number}		value 
+	 *  @param {Tone.Time}  time 
+	 */
+	Tone.Signal.prototype.setValueAtTime = function(value, time){
+		value *= this._syncRatio;
+		this.scalar.gain.setValueAtTime(value, this.toSeconds(time));
+	};
+
+	/**
+	 *  creates a schedule point with the current value at the current time
+	 *  
+	 *  @returns {number} the current value
+	 */
+	Tone.Signal.prototype.setCurrentValueNow = function(){
+		var now = this.now();
+		var currentVal = this.getValue();
+		this.cancelScheduledValues(now);
+		this.scalar.gain.setValueAtTime(currentVal, now);
+		return currentVal;
+	};
+
+	/**
+	 *  Schedules a linear continuous change in parameter value from the 
+	 *  previous scheduled parameter value to the given value.
+	 *  
+	 *  @param  {number} value   
+	 *  @param  {Tone.Time} endTime 
+	 */
+	Tone.Signal.prototype.linearRampToValueAtTime = function(value, endTime){
+		value *= this._syncRatio;
+		this.scalar.gain.linearRampToValueAtTime(value, this.toSeconds(endTime));
+	};
+
+	/**
+	 *  Schedules an exponential continuous change in parameter value from 
+	 *  the previous scheduled parameter value to the given value.
+	 *  
+	 *  @param  {number} value   
+	 *  @param  {Tone.Time} endTime 
+	 */
+	Tone.Signal.prototype.exponentialRampToValueAtTime = function(value, endTime){
+		value *= this._syncRatio;
+		this.scalar.gain.exponentialRampToValueAtTime(value, this.toSeconds(endTime));
+	};
+
+	/**
+	 *  Schedules an exponential continuous change in parameter value from 
+	 *  the current time and current value to the given value.
+	 *  
+	 *  @param  {number} value   
+	 *  @param  {Tone.Time} endTime 
+	 */
+	Tone.Signal.prototype.exponentialRampToValueNow = function(value, endTime){
+		this.setCurrentValueNow();
+		value *= this._syncRatio;
+		//make sure that the endTime doesn't start with +
+		if (endTime.toString().charAt(0) === "+"){
+			endTime = endTime.substr(1);
+		}
+		this.scalar.gain.exponentialRampToValueAtTime(value, this.now() + this.toSeconds(endTime));
+	};
+
+	/**
+	 *  Schedules an linear continuous change in parameter value from 
+	 *  the current time and current value to the given value at the given time.
+	 *  
+	 *  @param  {number} value   
+	 *  @param  {Tone.Time} endTime 
+	 */
+	Tone.Signal.prototype.linearRampToValueNow = function(value, endTime){
+		this.setCurrentValueNow();
+		value *= this._syncRatio;
+		//make sure that the endTime doesn't start with +
+		if (endTime.toString().charAt(0) === "+"){
+			endTime = endTime.substr(1);
+		}
+		this.scalar.gain.linearRampToValueAtTime(value, this.now() + this.toSeconds(endTime));
+	};
+
+	/**
+	 *  Start exponentially approaching the target value at the given time with
+	 *  a rate having the given time constant.
+	 *  	
+	 *  @param {number} value        
+	 *  @param {Tone.Time} startTime    
+	 *  @param {number} timeConstant 
+	 */
+	Tone.Signal.prototype.setTargetAtTime = function(value, startTime, timeConstant){
+		value *= this._syncRatio;
+		this.output.gain.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);
+	};
+
+	/**
+	 *  Sets an array of arbitrary parameter values starting at the given time
+	 *  for the given duration.
+	 *  	
+	 *  @param {Array<number>} values    
+	 *  @param {Tone.Time} startTime 
+	 *  @param {Tone.Time} duration  
+	 */
+	Tone.Signal.prototype.setValueCurveAtTime = function(values, startTime, duration){
+		for (var i = 0; i < values.length; i++){
+			values[i] *= this._syncRatio;
+		}
+		this.scalar.gain.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));
+	};
+
+	/**
+	 *  Cancels all scheduled parameter changes with times greater than or 
+	 *  equal to startTime.
+	 *  
+	 *  @param  {Tone.Time} startTime
+	 */
+	Tone.Signal.prototype.cancelScheduledValues = function(startTime){
+		this.scalar.gain.cancelScheduledValues(this.toSeconds(startTime));
+	};
+
+	/**
+	 *  Sync this to another signal and it will always maintain the 
+	 *  ratio between the two signals until it is unsynced
+	 *  
+	 *  @param  {Tone.Signal} signal to sync to
+	 */
+	Tone.Signal.prototype.sync = function(signal){
+		//get the sync ratio
+		if (signal.getValue() !== 0){
+			this._syncRatio = this.getValue() / signal.getValue();
+		} else {
+			this._syncRatio = 0;
+		}
+		//make a new scalar which is not connected to the constant signal
+		this.scalar.disconnect();
+		this.scalar = this.context.createGain();
+		this.chain(signal, this.scalar, this.output);
+		//set it ot the sync ratio
+		this.scalar.gain.value = this._syncRatio;
+	};
+
+	/**
+	 *  unbind the signal control
+	 *
+	 *  will leave the signal value as it was without the influence of the control signal
+	 */
+	Tone.Signal.prototype.unsync = function(){
+		//make a new scalar so that it's disconnected from the control signal
+		//get the current gain
+		var currentGain = this.getValue();
+		this.scalar.disconnect();
+		this.scalar = this.context.createGain();
+		this.scalar.gain.value = currentGain / this._syncRatio;
+		this._syncRatio = 1;
+		//reconnect things up
+		this.chain(constant, this.scalar, this.output);
+	};
+
+	return Tone.Signal;
+});
+define('Tone/signal/Add',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){
+
+	/**
+	 *  Adds a value to an incoming signal
+	 *
+	 *  @constructor
+	 *  @extends {Tone}
+	 *  @param {number} value
+	 */
+	Tone.Add = function(value){
+		Tone.call(this);
+
+		/**
+		 *  @private
+		 *  @type {Tone}
+		 */
+		this._value = new Tone.Signal(value);
+
+		//connections
+		this.chain(this._value, this.input, this.output);
+	};
+
+	Tone.extend(Tone.Add);
+
+	/**
+	 *  set the constant
+	 *  
+	 *  @param {number} value 
+	 */
+	Tone.Add.prototype.setValue = function(value){
+		this._value.setValue(value);
+	}; 
+
+	return Tone.Add;
+});
+define('Tone/signal/Multiply',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){
+
+	/**
+	 *  Multiply the incoming signal by some factor
+	 *
+	 *  @constructor
+	 *  @extends {Tone}
+	 *  @param {number=} value constant value to multiple
+	 */
+	Tone.Multiply = function(value){
+		/**
+		 *  the input node is the same as the output node
+		 *  it is also the GainNode which handles the scaling of incoming signal
+		 *  
+		 *  @type {GainNode}
+		 */
+		this.input = this.context.createGain();
+		/** @alias {GainNode} */
+		this.output = this.input;
+
+		//apply the inital scale factor
+		this.input.gain.value = this.defaultArg(value, 1);
+	};
+
+	Tone.extend(Tone.Multiply);
+
+	/**
+	 *  set the constant multiple
+	 *  	
+	 *  @param {number} value 
+	 */
+	Tone.Multiply.prototype.setValue = function(value){
+		this.input.gain.value = value;
+	};
+
+	return Tone.Multiply;
+});
+
+define('Tone/signal/Scale',["Tone/core/Tone", "Tone/signal/Add", "Tone/signal/Multiply"], function(Tone){
+	
+	/**
+	 *  performs a linear scaling on an input signal
+	 *
+	 *  scales from the input range of inputMin to inputMax 
+	 *  to the output range of outputMin to outputMax
+	 *
+	 *  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 
+	 */
+	Tone.Scale = function(inputMin, inputMax, outputMin, outputMax){
+		Tone.call(this);
+
+		//if there are only two args
+		if (arguments.length == 2){
+			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._scale = new Tone.Multiply(1);
+		/** @private 
+			@type {Tone.Add} */
+		this._plusOutput = new Tone.Add(0);
+
+		//connections
+		this.chain(this.input, this._plusInput, this._scale, this._plusOutput, this.output);
+
+		//set the scaling values
+		this._setScalingParameters();
+	};
+
+	Tone.extend(Tone.Scale);
+
+	/**
+	 *  set the scaling parameters
+	 *  
+	 *  @private
+	 */
+	Tone.Scale.prototype._setScalingParameters = function(){
+		//components
+		this._plusInput.setValue(-this._inputMin);
+		this._scale.setValue((this._outputMax - this._outputMin)/(this._inputMax - this._inputMin));
+		this._plusOutput.setValue(this._outputMin);
+	};
+
+	/**
+	 *  set the input min value
+	 *  @param {number} val 
+	 */
+	Tone.Scale.prototype.setInputMin = function(val){
+		this._inputMin = val;
+		this._setScalingParameters();
+	};
+
+	/**
+	 *  set the input max value
+	 *  @param {number} val 
+	 */
+	Tone.Scale.prototype.setInputMax = function(val){
+		this._inputMax = val;
+		this._setScalingParameters();
+	};
+
+	/**
+	 *  set the output min value
+	 *  @param {number} val 
+	 */
+	Tone.Scale.prototype.setOutputMin = function(val){
+		this._outputMin = val;
+		this._setScalingParameters();
+	};
+
+	/**
+	 *  set the output max value
+	 *  @param {number} val 
+	 */
+	Tone.Scale.prototype.setOutputMax = function(val){
+		this._outputMax = val;
+		this._setScalingParameters();
+	};
+
+	return Tone.Scale;
+});
+
+define('Tone/component/DryWet',["Tone/core/Tone", "Tone/signal/Signal", "Tone/signal/Scale"], function(Tone){
+
+	/**
+	 * DRY/WET KNOB
+	 * 
+	 * equal power fading control values:
+	 * 	0 = 100% dry
+	 * 	1 = 100% wet
+	 *
+	 * @constructor
+	 * @param {number} initialDry
+	 */		
+	Tone.DryWet = function(initialDry){
+		Tone.call(this);
+
+		//components
+		this.dry = this.context.createGain();
+		this.wet = this.context.createGain();
+		//control signal
+		this.control = new Tone.Signal();
+		this.invert = new Tone.Scale(1, 0);
+		this.normal = new Tone.Scale(0, 1);
+
+		//connections
+		this.dry.connect(this.output);
+		this.wet.connect(this.output);
+		//wet control
+		this.chain(this.control, this.invert, this.wet.gain);
+		//dry control
+		this.chain(this.control, this.normal, this.dry.gain);
+
+		//setup
+		this.dry.gain.value = 0;
+		this.wet.gain.value = 0;
+		this.setDry(0);
+	};
+
+	Tone.extend(Tone.DryWet);
+
+	/**
+	 * Set the dry value of the knob 
+	 * 
+	 * @param {number} val
+	 * @param {Tone.Time} rampTime
+	 */
+	Tone.DryWet.prototype.setDry = function(val, rampTime){
+		rampTime = this.defaultArg(rampTime, 0);
+		this.control.linearRampToValueAtTime(val*2 - 1, this.toSeconds(rampTime));
+	};
+
+	/**
+	 * Set the wet value of the knob 
+	 * 
+	 * @param {number} val
+	 * @param {Tone.Time} rampTime
+	 */
+	Tone.DryWet.prototype.setWet = function(val, rampTime){
+		this.setDry(1-val, rampTime);
+	};
+
+	return Tone.DryWet;
+});
+
+define('Tone/component/Envelope',["Tone/core/Tone", "Tone/signal/Signal"], function(Tone){
+
+	/**
+	 *  Envelope 
+	 *  ADR envelope generator attaches to an AudioParam
+	 *
+	 *  @constructor
+	 *  @extends {Tone}
+	 *  @param {Tone.Time=} attack
+	 *  @param {Tone.Time=} decay
+	 *  @param {number=} sustain 	a percentage (0-1) of the full amplitude
+	 *  @param {Tone.Time=} release
+	 *  @param {number=} minOutput the lowest point of the envelope
+	 *  @param {number=} maxOutput the highest point of the envelope
+	 */
+	Tone.Envelope = function(attack, decay, sustain, release, minOutput, maxOutput){
+		//extend Unit
+		Tone.call(this);
+
+		//set the parameters
+		this.attack = this.defaultArg(attack, 0.01);
+		this.decay = this.defaultArg(decay, 0.1);
+		this.release = this.defaultArg(release, 1);
+		this.sustain = this.defaultArg(sustain, 0.5);
+
+		this.min = this.defaultArg(minOutput, 0);
+		this.max = this.defaultArg(maxOutput, 1);
+		
+		//the control signal
+		this.control = new Tone.Signal(this.min);
+
+		//connections
+		this.chain(this.control, this.output);
+	};
+
+	Tone.extend(Tone.Envelope);
+
+	/**
+	 * attack->decay->sustain linear ramp
+	 * @param  {Tone.Time} time
+	 */
+	Tone.Envelope.prototype.triggerAttack = function(time){
+		var startVal = this.min;
+		if (!time){
+			startVal = this.control.getValue();
+		}
+		time = this.defaultArg(time, this.now());
+		time = this.toSeconds(time);
+		this.control.cancelScheduledValues(time);
+		this.control.setValueAtTime(startVal, time);
+		var attackTime = this.toSeconds(this.attack);
+		var decayTime = this.toSeconds(this.decay);
+		this.control.linearRampToValueAtTime(this.max, time + attackTime);
+		var sustainVal = (this.max - this.min) * this.sustain + this.min;
+		this.control.linearRampToValueAtTime(sustainVal, time + attackTime + decayTime);
+	};
+
+	/**
+	 * attack->decay->sustain exponential ramp
+	 * @param  {Tone.Time} time
+	 */
+	Tone.Envelope.prototype.triggerAttackExp = function(time){
+		var startVal = this.min;
+		if (!time){
+			startVal = this.control.getValue();
+		}
+		time = this.toSeconds(time);
+		this.control.cancelScheduledValues(time);
+		this.control.setValueAtTime(startVal, time);
+		var attackTime = this.toSeconds(this.attack);
+		var decayTime = this.toSeconds(this.decay);
+		this.control.linearRampToValueAtTime(this.max, time + attackTime);
+		var sustainVal = (this.max - this.min) * this.sustain + this.min;
+		this.control.exponentialRampToValueAtTime(sustainVal, time + attackTime + decayTime);
+	};
+
+	
+	/**
+	 * triggers the release of the envelope with a linear ramp
+	 * @param  {Tone.Time} time
+	 */
+	Tone.Envelope.prototype.triggerRelease = function(time){
+		var startVal = this.control.getValue();
+		if (time){
+			startVal = (this.max - this.min) * this.sustain + this.min;
+		}
+		time = this.toSeconds(time);
+		this.control.cancelScheduledValues(time);
+		this.control.setValueAtTime(startVal, time);
+		this.control.linearRampToValueAtTime(this.min, time + this.toSeconds(this.release));
+	};
+
+
+	/**
+	 * triggers the release of the envelope with an exponential ramp
+	 * 
+	 * @param  {Tone.Time} time
+	 */
+	Tone.Envelope.prototype.triggerReleaseExp = function(time){
+		var startVal = this.control.getValue();
+		if (time){
+			startVal = (this.max - this.min) * this.sustain + this.min;
+		}
+		time = this.toSeconds(time);
+		this.control.cancelScheduledValues(time);
+		this.control.setValueAtTime(startVal, time);
+		this.control.exponentialRampToValueAtTime(this.min, time + this.toSeconds(this.release));
+	};
+
+	/**
+	 * 	pointer to the parent's connect method
+	 * 	@private
+	 */
+	Tone.Envelope.prototype._connect = Tone.prototype.connect;
+
+	/**
+	 * connect the envelope
+	 * 
+	 * if the envelope is connected to a param, the params 
+	 * value will be set to 0 so that it doesn't interfere with the envelope
+	 * 
+	 * @param  {number} param
+	 */
+	Tone.Envelope.prototype.connect = function(param){
+		if (param instanceof AudioParam){
+			//set the initial value
+			param.value = 0;
+		} 
+		this._connect(param);
+	};
+
+	return Tone.Envelope;
+});
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//	MASTER OUTPUT
+//
+//	a single master output
+//	adds a toMaster method on AudioNodes and components
+///////////////////////////////////////////////////////////////////////////////
+
+
+define('Tone/core/Master',["Tone/core/Tone"], function(Tone){
+
+	var Master = function(){
+		//extend audio unit
+		Tone.call(this);
+
+		//put a hard limiter on the output so we don't blow any eardrums
+		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);
+	}
+
+	Tone.extend(Master);
+
+	///////////////////////////////////////////////////////////////////////////
+	//	Add toMaster methods
+	///////////////////////////////////////////////////////////////////////////
+
+	//@param {AudioNode|Tone=} unit
+	Tone.prototype.toMaster = function(){
+		this.connect(Tone.Master);
+	}
+
+	AudioNode.prototype.toMaster = function(){
+		this.connect(Tone.Master);
+	}
+
+	//a single master output
+	Tone.Master = new Master();
+
+	return Tone.Master;
+});
+define('Tone/core/Transport',["Tone/core/Tone", "Tone/core/Master", "Tone/signal/Signal"], 
+function(Tone){
+
+
+	/**
+	 *  oscillator-based transport allows for simple musical timing
+	 *  supports tempo curves and time changes
+	 *
+	 *  @constructor
+	 */
+	Tone.Transport = function(){
+
+		/**
+		 *  watches the main oscillator for timing ticks
+		 *  
+		 *  @private
+		 *  @type {ScriptProcessorNode}
+		 */
+		this._jsNode = this.context.createScriptProcessor(this.bufferSize, 1, 1);
+		this._jsNode.onaudioprocess = this._processBuffer.bind(this);
+
+		/** @type {boolean} */
+		this.loop = false;
+
+		//so it doesn't get garbage collected
+		this._jsNode.toMaster();
+	};
+
+	Tone.extend(Tone.Transport);
+
+	/** 
+	 * @private 
+	 * @type {number} 
+	 */
+	var transportTicks = 0;
+	/** 
+	 * @private
+	 * @type {number}
+	 */
+	var tatum = 12;
+	/** 
+	 * @private
+	 * @type {Boolean}
+	 */
+	var upTick = false;
+	/** 
+	 * @private
+	 * @type {number}
+	 */
+	var transportTimeSignature = 4;
+
+	/** 
+	 * @private
+	 * @type {number}
+	 */
+	var loopStart = 0;
+	/** 
+	 * @private
+	 * @type {number}
+	 */
+	var loopEnd = tatum * 4;
+
+	/** 
+	 * @private
+	 * @type {Array}
+	 */
+	var intervals = [];
+	/** 
+	 * @private
+	 * @type {Array}
+	 */
+	var timeouts = [];
+	/** 
+	 * @private
+	 * @type {Array}
+	 */
+	var timeline = [];
+	/** 
+	 * @private
+	 * @type {number}
+	 */
+	var timelineProgress = 0;
+
+	/**
+	 *  The main oscillator for the system
+	 *  @private
+	 *  @type {OscillatorNode}
+	 */
+	var oscillator = null;
+
+	/** 
+	 *  controls the oscillator frequency
+	 *  starts at 120bpm
+	 *  @private
+	 *  @type {Tone.Signal}
+	 */
+	var controlSignal = new Tone.Signal(120);
+
+	/** 
+	 *  All of the synced components
+	 *  @private 
+	 *  @type {Array<Tone>}
+	 */
+	var SyncedComponents = [];
+
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	JS NODE PROCESSING
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  called when a buffer is ready
+	 *  	
+	 *  @param  {AudioProcessingEvent} event
+	 */
+	Tone.Transport.prototype._processBuffer = function(event){
+		var now = this.defaultArg(event.playbackTime, this.now());
+		var bufferSize = this._jsNode.bufferSize;
+		var incomingBuffer = event.inputBuffer.getChannelData(0);
+		for (var i = 0; i < bufferSize; i++){
+			var sample = incomingBuffer[i];
+			if (sample > 0 && !upTick){
+				upTick = true;	
+				this._processTick(now + this.samplesToSeconds(i), i);
+			} else if (sample < 0 && upTick){
+				upTick = false;
+			}
+		}
+	};
+
+	//@param {number} tickTime
+	Tone.Transport.prototype._processTick = function(tickTime, i){
+		if (oscillator !== null){
+			transportTicks += 1;
+			processIntervals(tickTime);
+			processTimeouts(tickTime, i);
+			processTimeline(tickTime);
+			if (this.loop){
+				if (transportTicks === loopEnd){
+					this._setTicks(this.loopEnd);
+				}
+			}
+		}
+	};
+
+	//jump to a specific tick in the timeline
+	Tone.Transport.prototype._setTicks = function(ticks){
+		transportTicks = ticks;
+		for (var i = 0; i < timeline.length; i++){
+			var timeout = timeline[i];
+			if (timeout.callbackTick() >= ticks){
+				timelineProgress = i;
+				break;
+			}
+		}
+	};
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	EVENT PROCESSING
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  process the intervals
+	 *  @param  {number} time 
+	 */
+	var processIntervals = function(time){
+		for (var i = 0, len = intervals.length; i<len; i++){
+			var interval = intervals[i];
+			if (interval.testInterval(transportTicks)){
+				interval.doCallback(time);
+			}
+		}
+	};
+
+	/**
+	 *  process the timeouts
+	 *  @param  {number} time 
+	 */
+	var processTimeouts = function(time){
+		var removeTimeouts = 0;
+		for (var i = 0, len = timeouts.length; i<len; i++){
+			var timeout = timeouts[i];
+			var callbackTick = timeout.callbackTick();
+			if (callbackTick <= transportTicks){
+				timeout.doCallback(time);
+				removeTimeouts++;
+			} else if (callbackTick > transportTicks){
+				break;
+			} 
+		}
+		//remove the timeouts off the front of the array after they've been called
+		timeouts.splice(0, removeTimeouts);
+	};
+
+	/**
+	 *  process the timeline events
+	 *  @param  {number} time 
+	 */
+	var processTimeline = function(time){
+		for (var i = timelineProgress, len = timeline.length; i<len; i++){
+			var evnt = timeline[i];
+			var callbackTick = evnt.callbackTick();
+			if (callbackTick <= transportTicks){
+				evnt.doCallback(time);
+				timelineProgress = i;
+			} else if (callbackTick > transportTicks){
+				break;
+			} 
+		}
+	};
+
+	/**
+	 *  clear the timeouts and intervals
+	 */
+	function clearTimelineEvents(){
+		timeouts = [];
+		intervals = [];
+	}
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	INTERVAL
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  intervals are recurring events 
+	 *  
+	 *  @param {function} callback
+	 *  @param {Tone.Time}   interval 
+	 *  @param {Object}   ctx  the context the function is invoked in
+	 *  @return {number} the id of the interval
+	 */
+	Tone.Transport.prototype.setInterval = function(callback, interval, ctx){
+		var tickTime = this.toTicks(interval);
+		var timeout = new TimelineEvent(callback, ctx, tickTime, transportTicks);
+		intervals.push(timeout);
+		return timeout.id;
+	};
+
+	/**
+	 *  clear an interval from the processing array
+	 *  @param  {number} rmInterval 	the interval to remove
+	 *  @return {boolean}            	true if the event was removed
+	 */
+	Tone.Transport.prototype.clearInterval = function(rmInterval){
+		for (var i = 0; i < intervals.length; i++){
+			var interval = intervals[i];
+			if (interval.id === rmInterval){
+				intervals.splice(i, 1);
+				return true;
+			}
+		}
+		return false;
+	};
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	TIMEOUT
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  set a timeout to occur after time from now
+	 *  
+	 *  @param {function} callback 
+	 *  @param {Tone.Time}   time     
+	 *  @param {Object}   ctx      the context to invoke the callback in
+	 *  @return {number} the id of the timeout for clearing timeouts
+	 */
+	Tone.Transport.prototype.setTimeout = function(callback, time, ctx){
+		var ticks = this.toTicks(time);
+		var timeout = new TimelineEvent(callback, ctx, ticks + transportTicks, 0);
+		//put it in the right spot
+		for (var i = 0, len = timeouts.length; i<len; i++){
+			var testEvnt = timeouts[i];
+			if (testEvnt.callbackTick() > timeout.callbackTick()){
+				timeouts.splice(i, 0, timeout);
+				return timeout.id;
+			}
+		}
+		//otherwise push it on the end
+		timeouts.push(timeout);
+		return timeout.id;
+	};
+
+	/**
+	 *  clear the timeout based on it's ID
+	 *  @param  {number} timeoutID 
+	 *  @return {boolean}           true if the timeout was removed
+	 */
+	Tone.Transport.prototype.clearTimeout = function(timeoutID){
+		for (var i = 0; i < timeouts.length; i++){
+			var testTimeout = timeouts[i];
+			if (testTimeout.id === timeoutID){
+				timeouts.splice(i, 1);
+				return true;
+			}
+		}
+		return false;
+	};
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	TIMELINE
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  Timeline events are synced to the timeline of the Transport
+	 *  Unlike Timeout, Timeline events will restart after the 
+	 *  Transport has been stopped and restarted. 
+	 *
+	 *  
+	 *  @param {function} 	callback 	
+	 *  @param {Tome.Time}  timeout  
+	 *  @param {Object}   	ctx      	the context in which the funtion is called
+	 *  @return {number} 				the id for clearing the timeline event
+	 */
+	Tone.Transport.prototype.setTimeline = function(callback, timeout, ctx){
+		var ticks = this.toTicks(timeout);
+		ctx = this.defaultArg(ctx, window);
+		var timelineEvnt = new TimelineEvent(callback, ctx, ticks + transportTicks, 0);
+		//put it in the right spot
+		for (var i = timelineProgress, len = timeline.length; i<len; i++){
+			var testEvnt = timeline[i];
+			if (testEvnt.callbackTick() > timelineEvnt.callbackTick()){
+				timeline.splice(i, 0, timelineEvnt);
+				return timelineEvnt.id;
+			}
+		}
+		//otherwise push it on the end
+		timeline.push(event);
+		return timelineEvnt.id;
+	};
+
+	/**
+	 *  clear the timeline event from the 
+	 *  @param  {number} timelineID 
+	 *  @return {boolean} true if it was removed
+	 */
+	Tone.Transport.prototype.clearTimeline = function(timelineID){
+		for (var i = 0; i < timeline.length; i++){
+			var testTimeline = timeline[i];
+			if (testTimeline.id === timelineID){
+				timeline.splice(i, 1);
+				return true;
+			}
+		}
+		return false;
+	};
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	TIME CONVERSIONS
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  turns the time into
+	 *  @param  {Tone.Time} time
+	 *  @return {number}      
+	 */
+	Tone.Transport.prototype.toTicks = function(time){
+		//get the seconds
+		var seconds = this.toSeconds(time);
+		var quarter = this.notationToSeconds("4n");
+		var quarters = seconds / quarter;
+		var tickNum = quarters * tatum;
+		//quantize to tick value
+		return Math.round(tickNum);
+	};
+
+	/**
+	 *  get the transport time
+	 *  @return {string} in transportTime format (measures:beats:sixteenths)
+	 */
+	Tone.Transport.prototype.getTransportTime = function(){
+		var quarters = transportTicks / tatum;
+		var measures = Math.floor(quarters / transportTimeSignature);
+		var sixteenths = Math.floor((quarters % 1) * 4);
+		quarters = Math.floor(quarters) % transportTimeSignature;
+		var progress = [measures, quarters, sixteenths];
+		return progress.join(":");
+	};
+
+	/**
+	 *  set the transport time, jump to the position right away
+	 *  	
+	 *  @param {Tone.Time} progress 
+	 */
+	Tone.Transport.prototype.setTransportTime = function(progress){
+		var ticks = this.toTicks(progress);
+		this._setTicks(ticks);
+	};
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	START/STOP/PAUSE
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  start the transport and all sources synced to the transport
+	 *  
+	 *  @param  {Tone.Time} time
+	 */
+	Tone.Transport.prototype.start = function(time){
+		if (oscillator === null){
+			//reset the oscillator
+			oscillator = this.context.createOscillator();
+			oscillator.type = "square";
+			oscillator.connect(this._jsNode);
+			//connect it up
+			controlSignal.connect(oscillator.frequency);
+			oscillator.frequency.value = 0;
+		}
+		upTick = false;
+		oscillator.start(this.toSeconds(time));
+		//call start on each of the synced sources
+	};
+
+
+	/**
+	 *  stop the transport and all sources synced to the transport
+	 *  
+	 *  @param  {Tone.Time} time
+	 */
+	Tone.Transport.prototype.stop = function(time){
+		if (oscillator !== null){
+			oscillator.stop(this.toSeconds(time));
+			oscillator = null;
+		}
+		this._setTicks(0);
+		clearTimelineEvents();
+		//call stop on each of the synced sources
+	};
+
+	/**
+	 *  pause the transport and all sources synced to the transport
+	 *  
+	 *  @param  {Tone.Time} time
+	 */
+	Tone.Transport.prototype.pause = function(time){
+		oscillator.stop(this.toSeconds(time));
+		oscillator = null;
+		clearTimelineEvents();
+		//call pause on each of the synced sources
+	};
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	SETTERS/GETTERS
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  set the BPM
+	 *  optionally ramp to the bpm over some time
+	 *  @param {number} bpm   
+	 *  @param {Tone.Time=} rampTime 
+	 */
+	Tone.Transport.prototype.setBpm = function(bpm, rampTime){
+		//convert the bpm to frequency
+		var tatumFreq = this.toFrequency(tatum.toString() + "n", bpm, transportTimeSignature);
+		var freqVal = 4 * tatumFreq;
+		if (!rampTime){
+			controlSignal.cancelScheduledValues(0);
+			controlSignal.setValue(freqVal);
+		} else {
+			controlSignal.exponentialRampToValueNow(freqVal, rampTime);
+		}
+	};
+
+	/**
+	 *  return the current BPM
+	 *  
+	 *  @return {number} 
+	 */
+	Tone.Transport.prototype.getBpm = function(){
+		//convert the current frequency of the oscillator to bpm
+		var freq = controlSignal.getValue();
+		return 60 * (freq / tatum);
+	};
+
+	/**
+	 *  set the time signature
+	 *  
+	 *  @example
+	 *  this.setTimeSignature(4); //for 4/4
+	 *  
+	 *  @param {number} numerator   
+	 *  @param {number=} denominator defaults to 4
+	 */
+	Tone.Transport.prototype.setTimeSignature = function(numerator, denominator){
+		denominator = this.defaultArg(denominator, 4);
+		transportTimeSignature = numerator / (denominator / 4);
+	};
+
+	/**
+	 *  return the time signature as just the numerator
+	 *  over 4 is assumed. 
+	 *  for example 4/4 would return 4 and 6/8 would return 3
+	 *  
+	 *  @return {number} 
+	 */
+	Tone.Transport.prototype.getTimeSignature = function(){
+		return transportTimeSignature;
+	};
+
+	/**
+	 *  set the loop start position
+	 *  
+	 *  @param {Tone.Time} startPosition
+	 */
+	Tone.Transport.prototype.setLoopStart = function(startPosition){
+		loopStart = this.toTicks(startPosition);
+	};
+
+	/**
+	 *  set the loop start position
+	 *  
+	 *  @param {Tone.Time} endPosition
+	 */
+	Tone.Transport.prototype.setLoopEnd = function(endPosition){
+		loopEnd = this.toTicks(endPosition);
+	};
+
+	/**
+	 *  shorthand loop setting
+	 *  @param {Tone.Time} startPosition 
+	 *  @param {Tone.Time} endPosition   
+	 */
+	Tone.Transport.prototype.setLoopPoint = function(startPosition, endPosition){
+		this.setLoopStart(startPosition);
+		this.setLoopEnd(endPosition);
+	};
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	SYNCING
+	///////////////////////////////////////////////////////////////////////////////
+	
+
+	Tone.Transport.prototype.sync = function(source, controlSignal){
+		//create a gain node, attach it to the control signal
+		// var ratio = new Tone.Multiply();
+		// controlSignal.connect(ratio);
+		// return ratio;
+	};
+
+	/**
+	 *  remove the source from the list of Synced Sources
+	 *  
+	 *  @param  {Tone.Source} source [description]
+	 */
+	Tone.Transport.prototype.unsync = function(source){
+		
+	};
+
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	TIMELINE EVENT
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  @static
+	 *  @type {number}
+	 */
+	var TimelineEventIDCounter = 0;
+
+	/**
+	 *  A Timeline event
+	 *
+	 *  @constructor
+	 *  @param {function(number)} callback   
+	 *  @param {Object}   context    
+	 *  @param {number}   tickTime
+ 	 *  @param {number}   startTicks
+	 */
+	var TimelineEvent = function(callback, context, tickTime, startTicks){
+		this.startTicks = startTicks;
+		this.tickTime = tickTime;
+		this.callback = callback;
+		this.context = context;
+		this.id = TimelineEventIDCounter++;
+	};
+	
+	/**
+	 *  invoke the callback in the correct context
+	 *  passes in the playback time
+	 *  
+	 *  @param  {number} playbackTime 
+	 */
+	TimelineEvent.prototype.doCallback = function(playbackTime){
+		this.callback.call(this.context, playbackTime); 
+	};
+
+	/**
+	 *  get the tick which the callback is supposed to occur on
+	 *  
+	 *  @return {number} 
+	 */
+	TimelineEvent.prototype.callbackTick = function(){
+		return this.startTicks + this.tickTime;
+	};
+
+	/**
+	 *  test if the tick occurs on the interval
+	 *  
+	 *  @param  {number} tick 
+	 *  @return {boolean}      
+	 */
+	TimelineEvent.prototype.testInterval = function(tick){
+		return (tick - this.startTicks) % this.tickTime === 0;
+	};
+
+
+	///////////////////////////////////////////////////////////////////////////////
+	//	AUGMENT TONE'S PROTOTYPE TO INCLUDE TRANSPORT TIMING
+	///////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 *  tests if a string is musical notation
+	 *  i.e.:
+	 *  	4n = quarter note
+	 *   	2m = two measures
+	 *    	8t = eighth-note triplet
+	 *  
+	 *  @return {boolean} 
+	 */
+	Tone.prototype.isNotation = (function(){
+		var notationFormat = new RegExp(/[0-9]+[mnt]$/i);
+		return function(note){
+			return notationFormat.test(note);
+		};
+	})();
+
+	/**
+	 *  tests if a string is transportTime
+	 *  i.e. :
+	 *  	1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes
+	 *  	
+	 *  @return {boolean} 
+	 */
+	Tone.prototype.isTransportTime = (function(){
+		var transportTimeFormat = new RegExp(/^\d+(\.\d+)?:\d+(\.\d+)?(:\d+(\.\d+)?)?$/);
+		return function(transportTime){
+			return transportTimeFormat.test(transportTime);
+		};
+	})();
+
+	/**
+	 *  true if the input is in the format number+hz
+	 *  i.e.: 10hz
+	 *
+	 *  @param {number} freq 
+	 *  @return {boolean} 
+	 */
+	Tone.prototype.isFrequency = (function(){
+		var freqFormat = new RegExp(/[0-9]+hz$/i);
+		return function(freq){
+			return freqFormat.test(freq);
+		};
+	})();
+
+
+	/**
+	 *  convert notation format strings to seconds
+	 *  @param  {string} notation     
+	 *  @param {number=} bpm 
+	 *  @param {number=} timeSignature 
+	 *  @return {number}               
+	 */
+	Tone.prototype.notationToSeconds = function(notation, bpm, timeSignature){
+		bpm = this.defaultArg(bpm, Tone.Transport.getBpm());
+		timeSignature = this.defaultArg(timeSignature, transportTimeSignature);
+		var beatTime = (60 / bpm);
+		var subdivision = parseInt(notation, 10);
+		var beats = 0;
+		if (subdivision === 0){
+			beats = 0;
+		}
+		var lastLetter = notation.slice(-1);
+		if (lastLetter === "t"){
+			beats = (4 / subdivision) * 2/3;
+		} else if (lastLetter === "n"){
+			beats = 4 / subdivision;
+		} else if (lastLetter === "m"){
+			beats = subdivision * timeSignature;
+		} else {
+			beats = 0;
+		}
+		return beatTime * beats;
+	};
+
+	/**
+	 *  convert transportTime into seconds
+	 *  i.e.:
+	 *  	4:2:3 == 4 measures + 2 quarters + 3 sixteenths
+	 *  
+	 *  @param  {string} transportTime 
+	 *  @param {number=} bpm 
+	 *  @param {number=} timeSignature
+	 *  @return {number}               seconds
+	 */
+	Tone.prototype.transportTimeToSeconds = function(transportTime, bpm, timeSignature){
+		bpm = this.defaultArg(bpm, Tone.Transport.getBpm());
+		timeSignature = this.defaultArg(timeSignature, transportTimeSignature);
+		var measures = 0;
+		var quarters = 0;
+		var sixteenths = 0;
+		var split = transportTime.split(":");
+		if (split.length === 2){
+			measures = parseFloat(split[0]);
+			quarters = parseFloat(split[1]);
+		} else if (split.length === 1){
+			quarters = parseFloat(split[0]);
+		} else if (split.length === 3){
+			measures = parseFloat(split[0]);
+			quarters = parseFloat(split[1]);
+			sixteenths = parseFloat(split[2]);
+		}
+		var beats = (measures * timeSignature + quarters + sixteenths / 4);
+		return beats * this.notationToSeconds("4n");
+	};
+
+	/**
+	 *  Convert seconds to the closest transportTime in the form 
+	 *  	measures:quarters:sixteenths
+	 *  	
+	 *  @param {Tone.Time} seconds 
+	 *  @param {number=} bpm 
+	 *  @param {number=} timeSignature
+	 *  @return {string}         
+	 */
+	Tone.prototype.toTransportTime = function(time, bpm, timeSignature){
+		var seconds = this.toSeconds(time, bpm, timeSignature);
+		bpm = this.defaultArg(bpm, Tone.Transport.getBpm());
+		timeSignature = this.defaultArg(timeSignature, transportTimeSignature);
+		var quarterTime = this.notationToSeconds("4n");
+		var quarters = seconds / quarterTime;
+		var measures = Math.floor(quarters / timeSignature);
+		var sixteenths = Math.floor((quarters % 1) * 4);
+		quarters = Math.floor(quarters) % timeSignature;
+		var progress = [measures, quarters, sixteenths];
+		return progress.join(":");
+	};
+
+	/**
+	 *  convert a time to a frequency
+	 *  	
+	 *  @param  {Tone.Time} time 
+	 *  @return {number}      the time in hertz
+	 */
+	Tone.prototype.toFrequency = function(time, bpm, timeSignature){
+		if (this.isFrequency(time)){
+			return parseFloat(time);
+		} else if (this.isNotation(time) || this.isTransportTime(time)) {
+			return this.secondsToFrequency(this.toSeconds(time, bpm, timeSignature));
+		} else {
+			return time;
+		}
+	};
+
+	/**
+	 *  convert Tone.Time into seconds
+	 *  
+	 *  unlike the method which it overrides, this takes into account 
+	 *  transporttime and musical notation
+	 *  
+	 *  @param  {Tone.Time} time       
+	 *  @param  {number=} 	bpm 
+	 *  @param  {number=} 	timeSignature   
+	 */
+	Tone.prototype.toSeconds = function(time, bpm, timeSignature){
+		if (typeof time === "number"){
+			return time; //assuming that it's seconds
+		} else if (typeof time === "string"){
+			var plusTime = 0;
+			if(time.charAt(0) === "+") {
+				plusTime = this.now();
+				time = time.slice(1);				
+			} 
+			if (this.isNotation(time)){
+				time = this.notationToSeconds(time, bpm, timeSignature);
+			} else if (this.isTransportTime(time)){
+				time = this.transportTimeToSeconds(time, bpm, timeSignature);
+			} else if (this.isFrequency(time)){
+				time = this.frequencyToSeconds(time, bpm, timeSignature);
+			} else {
+				time = parseFloat(time);
+			}
+			return time + plusTime;
+		} else {
+			return this.now();
+		}
+	};
+
+	//a single transport object
+	Tone.Transport = new Tone.Transport();
+
+	return Tone.Transport;
+});
+
+define('Tone/source/Source',["Tone/core/Tone"], 
+function(Tone){
+
+	/**
+	 *  base class for sources
+	 *
+	 *  @constructor
+	 *  @extends {Tone}
+	 */	
+	Tone.Source = function(){
+		/**
+		 *  unlike most ToneNodes, Sources only have an output and no input
+		 *  
+		 *  @type {GainNode}
+		 */
+		this.output = this.context.createGain();
+	};
+
+	Tone.extend(Tone.Source);
+
+	/**
+	 *  @abstract
+	 *  @param  {Tone.Time} time 
+	 */
+	Tone.Source.prototype.start = function(){};
+
+	/**
+ 	 *  @abstract
+	 *  @param  {Tone.Time} time 
+	 */
+	Tone.Source.prototype.stop = function(){};
+
+	/**
+ 	 *  @abstract
+	 *  @param  {Tone.Time} time 
+	 */
+	Tone.Source.prototype.pause = function(){};
+
+	/**
+	 *  @param {number} value 
+	 *  @param {Tone.Time} time (relative to 'now')
+	 */
+	Tone.Source.prototype.fadeTo = function(value, time){
+		var currentVolume = this.output.gain.value;
+		var now = this.now();
+		this.output.gain.cancelScheduledValues(now);
+		this.output.gain.setValueAtTime(currentVolume, now);
+		this.output.gain.linearRampToValueAtTime(value, this.toSeconds(time));
+	};
+
+	/**
+	 *  @param {number} value 
+	 */
+	Tone.Source.prototype.setVolume = function(value){
+		this.output.gain.value = value;
+	};
+
+	return Tone.Source;
+});
+define('Tone/source/Oscillator',["Tone/core/Tone", "Tone/core/Transport", "Tone/signal/Signal", "Tone/source/Source"], 
+function(Tone){
+
+	/**
+	 *  Oscillator
+	 *
+	 *  Oscilator with start, pause, stop and sync to Transport
+	 *
+	 *  @constructor
+	 *  @extends {Tone.Source}
+	 *  @param {number|string=} freq starting frequency
+	 *  @param {string=} type type of oscillator (sine|square|triangle|sawtooth)
+	 */
+	Tone.Oscillator = function(freq, type){
+		Tone.Source.call(this);
+
+		/**
+		 *  the main oscillator
+		 *  @type {OscillatorNode}
+		 */
+		this.oscillator = this.context.createOscillator();
+		/**
+		 *  the frequency control signal
+		 *  @type {Tone.Signal}
+		 */
+		this.frequency = new Tone.Signal(this.defaultArg(this.toFrequency(freq), 440));
+
+		//connections
+		this.oscillator.connect(this.output);
+		//setup
+		this.oscillator.type = this.defaultArg(type, "sine");
+	};
+
+	Tone.extend(Tone.Oscillator, Tone.Source);
+
+	/**
+	 *  start the oscillator
+	 *  
+	 *  @param  {Tone.Time} time 
+	 */
+	Tone.Oscillator.prototype.start = function(time){
+		//get previous values
+		var type = this.oscillator.type;
+		var detune = this.oscillator.frequency.value;
+		//new oscillator with previous values
+		this.oscillator = this.context.createOscillator();
+		this.oscillator.type = type;
+		this.oscillator.detune.value = detune;
+		//connect the control signal to the oscillator frequency
+		this.oscillator.connect(this.output);
+		this.frequency.connect(this.oscillator.frequency);
+		this.oscillator.frequency.value = 0;
+		//start the oscillator
+		this.oscillator.start(this.toSeconds(time));
+	};
+
+	/**
+	 *  Sync the oscillator to the transport
+	 *
+	 *  the current ratio between the oscillator and the Transport BPM
+	 *  is fixed and any change to the Transport BPM will change this
+	 *  oscillator in that same ratio
+	 *
+	 *  Transport start/pause/stop will also start/pause/stop the oscillator
+	 */
+	Tone.Oscillator.prototype.sync = function(){
+		Tone.Transport.sync(this, this.frequency);
+	};
+
+	/**
+	 *  unsync the oscillator from the Transport
+	 */
+	Tone.Oscillator.prototype.unsync = function(){
+		Tone.Transport.unsync(this);
+		this.frequency.unsync();
+	};
+
+	/**
+	 *  stop the oscillator
+	 *  @param  {Tone.Time=} time (optional) timing parameter
+	 */
+	Tone.Oscillator.prototype.stop = function(time){
+		this.oscillator.stop(this.toSeconds(time));
+	};
+
+	/**
+	 *  exponentially ramp the frequency of the oscillator over the rampTime
+	 *  
+	 *  @param {Tone.Time}	val
+	 *  @param {Tone.Time=} rampTime when the oscillator will arrive at the frequency
+	 */
+	Tone.Oscillator.prototype.setFrequency = function(val, rampTime){
+		this.frequency.exponentialRampToValueAtTime(this.toFrequency(val), this.toSeconds(rampTime));
+	};
+
+	/**
+	 *  set the oscillator type
+	 *  
+	 *  @param {string} type (sine|square|triangle|sawtooth)
+	 */
+	Tone.Oscillator.prototype.setType = function(type){
+		this.oscillator.type = type;
+	};
+
+	return Tone.Oscillator;
+});
+define('Tone/component/LFO',["Tone/core/Tone", "Tone/source/Oscillator", "Tone/signal/Scale"], function(Tone){
+
+	/**
+	 *  Low Frequency Oscillator
+	 *
+	 *  LFO produces an output signal which can be attached to an AudioParam
+	 *  	for constant control over that parameter
+	 *  	the LFO can also be synced to the transport
+	 *
+	 *  @constructor
+	 *  @extends {Tone}
+	 *  @param {number} rate      
+	 *  @param {number=} outputMin 
+	 *  @param {number=} outputMax
+	 */
+	Tone.LFO = function(rate, outputMin, outputMax){
+
+		Tone.call(this);
+
+		/** @type {Tone.Oscillator} */
+		this.oscillator = new Tone.Oscillator(rate, "sine");
+		/** @type {Tone.Scale} */
+		this.scaler = new Tone.Scale(this.defaultArg(outputMin, 0), this.defaultArg(outputMax, 1));
+
+		//connect it up
+		this.chain(this.oscillator, this.scaler, this.output);
+	};
+
+	Tone.extend(Tone.LFO);
+
+
+	/**
+	 *  start the LFO
+	 *  @param  {Tone.Time} time 
+	 */
+	Tone.LFO.prototype.start = function(time){
+		this.oscillator.start(time);
+	};
+
+	/**
+	 *  stop the LFO
+	 *  @param  {Tone.Time} time 
+	 */
+	Tone.LFO.prototype.stop = function(time){
+		this.oscillator.stop(time);
+	};
+
+	/**
+	 *  Sync the start/stop/pause to the transport 
+	 *  and the frequency to the bpm of the transport
+	 */
+	Tone.LFO.prototype.sync = function(){
+		this.oscillator.sync();
+	};
+
+	/**
+	 *  unsync the LFO from transport control
+	 */
+	Tone.LFO.prototype.unsync = function(){
+		this.oscillator.unsync();
+	};
+
+
+	/**
+	 *  set the frequency
+	 *  @param {number} rate 
+	 */
+	Tone.LFO.prototype.setFrequency = function(rate){
+		this.oscillator.setFrequency(rate);
+	};
+
+	/**
+	 *  set the minimum output of the LFO
+	 *  @param {number} min 
+	 */
+	Tone.LFO.prototype.setMin = function(min){
+		this.scaler.setOutputMin(min);
+	};
+
+	/**
+	 *  set the maximum output of the LFO
+	 *  @param {number} min 
+	 */
+	Tone.LFO.prototype.setMax = function(max){
+		this.scaler.setOuputMax(max);
+	};
+
+	/**
+	 *  set the waveform of the LFO
+	 *  @param {string} type 
+	 */
+	Tone.LFO.prototype.setType = function(type){
+		this.oscillator.setType(type);
+	};
+
+	/**
+	 *  pointer to the parent's connect method
+	 *  @private
+	 */
+	Tone.LFO.prototype._connect = Tone.prototype.connect;
+
+	/**
+	 *	override the connect method so that it 0's out the value 
+	 *	if attached to an AudioParam
+	 *	
+	 *  @override
+	 *  @param  {AudioNode|AudioParam|Tone} param 
+	 */
+	Tone.LFO.prototype.connect = function(param){
+		if (param instanceof AudioParam){
+			//set the initial value
+			param.value = 0;
+		} 
+		this._connect(param);
+	};
+
+	return Tone.LFO;
+});
+define('Tone/component/Meter',["Tone/core/Tone", "Tone/core/Master"], function(Tone){
+
+	/**
+	 *  get the rms of the input signal with some averaging
+	 *  can also just get the value of the signal
+	 *  or the value in dB
+	 *  
+	 *  inspired by https://github.com/cwilso/volume-meter/blob/master/volume-meter.js
+	 *  The MIT License (MIT) Copyright (c) 2014 Chris Wilson
+	 *
+	 *  @constructor
+	 *  @extends {Tone}
+	 *  @param {number=} channels (optional) number of channels being metered
+	 *  @param {number=} smoothing (optional) amount of smoothing applied to the volume
+	 *  @param {number=} clipMemory (optional) number in ms that a "clip" should be remembered
+	 */
+	Tone.Meter = function(channels, smoothing, clipMemory){
+		//extends Unit
+		Tone.call(this);
+
+		/** @type {number} */
+		this.channels = this.defaultArg(channels, 1);
+
+		/** @type {number} */
+		this.smoothing = this.defaultArg(smoothing, 0.8);
+
+		/** @type {number} */
+		this.clipMemory = this.defaultArg(clipMemory, 500);
+
+		/** 
+		 *  the rms for each of the channels
+		 *  @private
+		 *  @type {Array<number>}
+		 */
+		this._volume = new Array(this.channels);
+
+		/** 
+		 *  the raw values for each of the channels
+		 *  @private
+		 *  @type {Array<number>}
+		 */
+		this._values = new Array(this.channels);
+
+		//zero out the volume array
+		for (var i = 0; i < this.channels; i++){
+			this._volume[i] = 0;
+			this._values[i] = 0;
+		}
+
+		/** 
+		 *  last time the values clipped
+		 *  @private
+		 *  @type {number}
+		 */
+		this._lastClip = 0;
+		
+		/** 
+		 *  @private
+		 *  @type {ScriptProcessorNode}
+		 */
+		this._jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, 1);
+		this._jsNode.onaudioprocess = this._onprocess.bind(this);
+		//so it doesn't get garbage collected
+		this._jsNode.toMaster();
+
+		//signal just passes
+		this.input.connect(this.output);
+		this.input.connect(this._jsNode);
+	};
+
+	Tone.extend(Tone.Meter);
+
+	/**
+	 *  called on each processing frame
+	 *  @private
+	 *  @param  {AudioProcessingEvent} event 
+	 */
+	Tone.Meter.prototype._onprocess = function(event){
+		var bufferSize = this._jsNode.bufferSize;
+		var smoothing = this.smoothing;
+		for (var channel = 0; channel < this.channels; channel++){
+			var input = event.inputBuffer.getChannelData(channel);
+			var sum = 0;
+			var total = 0;
+			var x;
+			var clipped = false;
+			for (var i = 0; i < bufferSize; i++){
+				x = input[i];
+				if (!clipped && x > 0.95){
+					clipped = true;
+					this._lastClip = Date.now();
+				}
+				total += x;
+		    	sum += x * x;
+			}
+			var average = total / bufferSize;
+			var rms = Math.sqrt(sum / bufferSize);
+			this._volume[channel] = Math.max(rms, this._volume[channel] * smoothing);
+			this._values[channel] = average;
+		}
+	};
+
+	/**
+	 *  get the rms of the signal
+	 *  	
+	 *  @param  {number=} channel which channel
+	 *  @return {number}         the value
+	 */
+	Tone.Meter.prototype.getLevel = function(channel){
+		channel = this.defaultArg(channel, 0);
+		var vol = this._volume[channel];
+		if (vol < 0.00001){
+			return 0;
+		} else {
+			return vol;
+		}
+	};
+
+	/**
+	 *  get the value of the signal
+	 *  @param  {number=} channel 
+	 *  @return {number}         
+	 */
+	Tone.Meter.prototype.getValue = function(channel){
+		channel = this.defaultArg(channel, 0);
+		return this._values[channel];
+	};
+
+	/**
+	 *  get the volume of the signal in dB
+	 *  @param  {number=} channel 
+	 *  @return {number}         
+	 */
+	Tone.Meter.prototype.getDb = function(channel){
+		return this.gainToDb(this.getLevel(channel));
+	};
+
+	// @returns {boolean} if the audio has clipped in the last 500ms
+	Tone.Meter.prototype.isClipped = function(){
+		return Date.now() - this._lastClip < this.clipMemory;
+	};
+
+	return Tone.Meter;
+});
+define('Tone/signal/Merge',["Tone/core/Tone"], function(Tone){
+
+	/**
+	 *  merge a left and a right channel into a single stereo channel
+	 *
+	 *  instead of connecting to the input, connect to either the left, or right input
+	 *
+	 *  default input for connect is left input
+	 *
+	 *  @constructor
+	 *  @extends {Tone}
+	 */
+	Tone.Merge = function(){
+
+		Tone.call(this);
+
+		/**
+		 *  the left input channel
+		 *  also an alias for the input
+		 *  @type {GainNode}
+		 */
+		this.left = this.input;
+		/**
+		 *  the right input channel
+		 *  @type {GainNode}
+		 */
+		this.right = this.context.createGain();
+		/**
+		 *  the merger node for the two channels
+		 *  @type {ChannelMergerNode}
+		 */
+		this.merger = this.context.createChannelMerger(2);
+
+		//connections
+		this.left.connect(this.merger, 0, 0);
+		this.right.connect(this.merger, 0, 1);
+		this.merger.connect(this.output);
+	};
+
+	Tone.extend(Tone.Merge);
+
+	return Tone.Merge;
+});
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  PANNER
+//
+//	Equal Power Gain L/R Panner. Not 3D
+//	0 = 100% Left
+//	1 = 100% Right
+///////////////////////////////////////////////////////////////////////////////
+
+define('Tone/component/Panner',["Tone/core/Tone", "Tone/signal/Merge", "Tone/signal/Signal", "Tone/signal/Scale"], 
+function(Tone){
+
+	Tone.Panner = function(){
+		Tone.call(this);
+
+		//components
+		//incoming signal is sent to left and right
+		this.left = this.context.createGain();
+		this.right = this.context.createGain();
+		this.control = new Tone.Signal();
+		this.merge = new Tone.Merge();
+		this.invert = new Tone.Scale(1, 0);
+		this.normal = new Tone.Scale(0, 1);
+
+		//connections
+		this.chain(this.input, this.left, this.merge.left);
+		this.chain(this.input, this.right, this.merge.right);
+		this.merge.connect(this.output);
+		//left channel control
+		this.chain(this.control, this.invert, this.left.gain);
+		//right channel control
+		this.chain(this.control, this.normal, this.right.gain);
+
+
+		//setup
+		this.left.gain.value = 0;
+		this.right.gain.value = 0;
+		this.setPan(.5);
+	}
+
+	Tone.extend(Tone.Panner);
+
+	Tone.Panner.prototype.setPan = function(val, rampTime){
+		rampTime = this.defaultArg(rampTime, 0);
+		//put val into -1 to 1 range
+		this.control.linearRampToValueAtTime(val * 2 - 1, rampTime);
+	}
+
+	return Tone.Panner;
+});;
+define('Tone/component/Recorder',["Tone/core/Tone", "Tone/core/Master"], function(Tone){
+
+	/**
+	 *  Record an input into an array or AudioBuffer
+	 *
+	 *  it is limited in that the recording length needs to be known beforehand
+	 *
+	 *  @constructor
+	 *  @extends {Tone}
+	 *  @param {number} channels 
+	 */
+	Tone.Recorder = function(channels){
+
+		Tone.call(this);
+
+		/**
+		 *  the number of channels in the recording
+		 *  @type {number}
+		 */
+		this.channels = this.defaultArg(channels, 1);
+
+		/**
+		 *  @private
+		 *  @type {ScriptProcessorNode}
+		 */
+		this._jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, 1);
+		this._jsNode.onaudioprocess = this._audioprocess.bind(this);
+
+		/**
+		 *  Float32Array for each channel
+		 *  @private
+		 *  @type {Array<Float32Array>}
+		 */
+		this._recordBuffers = new Array(this.channels);
+
+		/** 
+		 *  @private
+		 *  @type {number}
+		 */
+		this._recordBufferOffset = 0;
+
+		//connect it up
+		this.input.connect(this._jsNode);
+		//pass thru audio
+		this.input.connect(this.output);
+		//so it doesn't get garbage collected
+		this._jsNode.toMaster();
+		//clear it to start
+		this.clear();
+	};
+
+	Tone.extend(Tone.Recorder);
+
+	/**
+	 *  internal method called on audio process
+	 *  
+	 *  @private
+	 *  @param   {AudioProcessorEvent} event 
+	 */
+	Tone.Recorder.prototype._audioprocess = function(event){
+		if (this._recordBuffers[0] === null || this._recordBuffers[0].length - this._recordBufferOffset === 0){
+			return;
+		}
+		var input = event.inputBuffer;
+		var totalWrittenToBuffer = 0;
+		var recordBufferLength = this._recordBuffers[0].length;
+		for (var channelNum = 0; channelNum < input.numberOfChannels; channelNum++){
+			var bufferOffset = this._recordBufferOffset;
+			var channel = input.getChannelData(channelNum);
+			var bufferLen = channel.length;
+			if (recordBufferLength - bufferOffset > bufferLen){
+				this._recordBuffers[channelNum].set(channel, bufferOffset);
+				totalWrittenToBuffer += bufferLen;
+			} else {
+				for (var i = 0; i < bufferLen; i++) {
+					if (recordBufferLength > bufferOffset){
+						this._recordBuffers[channelNum][bufferOffset] = channel[i];
+						bufferOffset++;
+						totalWrittenToBuffer++;
+					} else {
+						break;
+					}
+				}
+			}
+		}
+		this._recordBufferOffset += totalWrittenToBuffer / input.numberOfChannels;
+	};
+
+	/**
+	 *  Record for a certain period of time
+	 *  
+	 *  will clear the internal buffer before starting
+	 *  
+	 *  @param  {Tone.Time} time 
+	 */
+	Tone.Recorder.prototype.record = function(time){
+		this.clear();
+		var recordBufferLength = this.toSamples(time);
+		for (var i = 0; i < this.channels; i++){
+			this._recordBuffers[i] = new Float32Array(recordBufferLength);
+		}
+	};
+
+	/**
+	 *  clears the recording buffer
+	 */
+	Tone.Recorder.prototype.clear = function(){
+		for (var i = 0; i < this.channels; i++){
+			this._recordBuffers[i] = null;
+		}
+		this._recordBufferOffset = 0;
+	};
+
+
+	/**
+	 *  true if there is nothing in the buffers
+	 *  @return {boolean} 
+	 */
+	Tone.Recorder.prototype.isEmpty = function(){
+		return this._recordBuffers[0] === null;
+	};
+
+	/**
+	 *  @return {Array<Float32Array>}
+	 */
+	Tone.Recorder.prototype.getFloat32Array = function(){
+		if (this.isEmpty()){
+			return null;
+		} else {
+			return this._recordBuffers;
+		}
+	};
+
+	/**
+	 *  @return {AudioBuffer}
+	 */
+	Tone.Recorder.prototype.getAudioBuffer = function(){
+		if (this.isEmpty()){
+			return null;
+		} else {
+			var audioBuffer = this.context.createBuffer(this.channels, this._recordBuffers[0].length, this.context.sampleRate);
+			for (var channelNum = 0; channelNum < audioBuffer.numberOfChannels; channelNum++){
+				var channel = audioBuffer.getChannelData(channelNum);
+				channel.set(this._recordBuffers[channelNum]);
+			}
+			return audioBuffer;
+		}
+	};
+
+
+	return Tone.Recorder;
+});
+define('Tone/core/Bus',["Tone/core/Tone"], function(Tone){
+
+	/**
+	 *  @fileOverview 
+	 *
+	 *  buses are another way of routing audio
+	 *
+	 *  augments Tone.prototype to include send and recieve
+	 */
+
+	 /**
+	  *  All of the routes
+	  *  
+	  *  @type {Object}
+	  */
+	var Buses = {};
+
+	/**
+	 *  send signal to a channel name
+	 *  
+	 *  @param  {string} channelName 
+	 *  @param  {number} amount      
+	 *  @return {GainNode}             
+	 */
+	Tone.prototype.send = function(channelName, amount){
+		if (!Buses.hasOwnProperty(channelName)){
+			Buses[channelName] = this.context.createGain();
+		}
+		var sendKnob = this.context.createGain();
+		sendKnob.gain.value = this.defaultArg(amount, 1);
+		this.chain(this.output, sendKnob, Buses[channelName]);
+		return sendKnob;		
+	};
+
+	/**
+	 *  recieve the input from the desired channelName to the input gain of 'this' node.
+	 *  	
+	 *  @param  {string} channelName 
+	 */
+	Tone.prototype.receive = function(channelName){
+		if (!Buses.hasOwnProperty(channelName)){
+			Buses[channelName] = this.context.createGain();	
+		}
+		Buses[channelName].connect(this.input);
+	};
+
+	// Tone.Buses = Buses;
+
+	// return Buses;
+});
+///////////////////////////////////////////////////////////////////////////////
+//
+//  EFFECTS UNIT
+//
+// 	connect the effect to the effectSend and to the effectReturn
+//	setDry(-1) = 100% Wet
+//	setDry(1) = 100% Dry
+///////////////////////////////////////////////////////////////////////////////
+
+define('Tone/effects/Effect',["Tone/core/Tone", "Tone/component/DryWet"], function(Tone){
+
+	Tone.Effect = function(){
+		//extends Unit
+		Tone.call(this);
+
+		//components
+		this.dryWet = new Tone.DryWet();
+		this.effectSend = this.context.createGain();
+		this.effectReturn = this.context.createGain();
+
+		//connections
+		this.input.connect(this.dryWet.dry);
+		this.input.connect(this.effectSend);
+		this.effectReturn.connect(this.dryWet.wet);
+		this.dryWet.connect(this.output);
+		
+		//setup
+		this.setDry(0);
+	}
+
+	Tone.extend(Tone.Effect, Tone);
+
+	//adjust the dry/wet balance
+	//dryness -1 to 1
+	// 1 = 100% dry
+	//-1 = 100% wet
+	//@param {number} dryness
+	//@param {number=} rampTime
+	Tone.Effect.prototype.setDry = function(dryness, rampTime){
+		this.dryWet.setDry(dryness, rampTime)
+	}
+
+	//@param {number} dryness
+	//@param {number=} rampTime
+	Tone.Effect.prototype.setWet = function(wetVal, rampTime){
+		this.setDry(-wetVal, rampTime);
+	}
+
+	Tone.Effect.prototype.bypass = function(){
+		this.setDry(1, 0);
+	}
+
+	Tone.Effect.prototype.connectEffect = function(effect){
+		this.chain(this.effectSend, effect, this.effectReturn);
+	}
+
+	return Tone.Effect;
+});
+define('Tone/effects/AutoPanner',["Tone/core/Tone", "Tone/source/Oscillator", "Tone/component/Panner", "Tone/effects/Effect"], function(Tone){
+
+	/**
+	* AutoPanner creates a left-right panner effect (not a 3D panner).
+	*
+	* @constructor
+	* @param { number= } rate (optional) rate in HZ of the left-right pan
+	* @param { number= } amount (optional) of the pan in dB (0 - 1)
+	*/
+	Tone.AutoPanner = function(rate, amount){
+		Tone.Effect.call(this);
+
+		//defaults
+		amount = this.defaultArg(amount, 1);
+		rate = this.defaultArg(rate, 1);
+
+		//components
+		this.osc = new Tone.Oscillator(rate);
+		this.amount = this.context.createGain();
+		this.panner = new Tone.Panner();
+
+		//connections
+		this.connectEffect(this.panner);
+		this.chain(this.osc, this.amount, this.panner.control);
+	};
+
+	//extend Effect
+	Tone.extend(Tone.AutoPanner, Tone.Effect);
+	
+	/**
+	 * Start the panner
+	 * 
+	 * @param {Tone.Time} Time the panner begins.
+	 */
+	Tone.AutoPanner.prototype.start = function(time){
+		this.osc.start(time);
+	};
+
+	/**
+	 * Stop the panner
+	 * 
+	 * @param {Tone.Time} time the panner stops.
+	 */
+	Tone.AutoPanner.prototype.stop = function(time){
+		this.osc.stop(time);
+	};
+
+	/**
+	 * Set the type of oscillator attached to the AutoPanner.
+	 * 
+	 * @param {string} type of oscillator the panner is attached to (sine|sawtooth|triangle|square)
+	 */
+	Tone.AutoPanner.prototype.setType = function(type){
+		this.osc.setType(type);
+	};
+
+	/**
+	 * Set frequency of the oscillator attached to the AutoPanner.
+	 * 
+	 * @param {number|string} rate in HZ of the oscillator's frequency.
+	 */
+	Tone.AutoPanner.prototype.setFrequency = function(rate){
+		this.osc.setFrequency(rate);
+	};
+
+	/**
+	 * Set the amount of the AutoPanner.
+	 * 
+	 * @param {number} amount in dB (0 - 1)
+	 */
+	Tone.AutoPanner.prototype.setAmount = function(amount){
+		this.amount.gain.value = amount;
+	};
+
+	return Tone.AutoPanner;
+});
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  FEEDBACK EFFECTS
+//
+// 	an effect with feedback
+///////////////////////////////////////////////////////////////////////////////
+
+define('Tone/effects/FeedbackEffect',["Tone/core/Tone", "Tone/effects/Effect"], function(Tone){
+
+	Tone.FeedbackEffect = function(){
+		//extends Unit
+		Tone.Effect.call(this);
+
+		this.feedback = this.context.createGain();
+		//feedback loop
+		this.chain(this.effectReturn, this.feedback, this.effectSend);
+
+		//some initial values
+		this.setFeedback(0);
+	}
+
+	Tone.extend(Tone.FeedbackEffect, Tone.Effect);
+
+	Tone.FeedbackEffect.prototype.setFeedback = function(fback){
+		this.rampToValueNow(this.feedback.gain, fback);
+	}
+
+	return Tone.FeedbackEffect;
+});
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//	FEEDBACK DELAY
+//
+///////////////////////////////////////////////////////////////////////////////
+
+define('Tone/effects/FeedbackDelay',["Tone/core/Tone", "Tone/effects/FeedbackEffect"], function(Tone){
+
+	//@param {number} delayTime
+	Tone.FeedbackDelay = function(delayTime){
+		Tone.FeedbackEffect.call(this);
+
+		this.delay = this.context.createDelay(4);
+		this.delay.delayTime.value = this.toSeconds(this.defaultArg(delayTime, .25));
+
+		//connect it up
+		this.connectEffect(this.delay);
+	}
+
+	Tone.extend(Tone.FeedbackDelay, Tone.FeedbackEffect);
+
+	Tone.FeedbackDelay.prototype.setDelayTime = function(delayTime){
+		this.rampToValueNow(this.delay.delayTime, this.toSeconds(delayTime));
+	}
+
+	return Tone.FeedbackDelay;
+});
+///////////////////////////////////////////////////////////////////////////////
+//
+//	PING PONG DELAY
+//
+///////////////////////////////////////////////////////////////////////////////
+
+define('Tone/effects/PingPongDelay',["Tone/core/Tone", "Tone/effects/FeedbackDelay"], function(Tone){
+
+
+	//@param {number=} delayTime
+	Tone.PingPongDelay = function(delayTime){
+		Tone.StereoSplit.call(this);
+
+		//components
+		this.leftDelay = new Tone.FeedbackDelay(delayTime);
+		this.rightDelay = new Tone.FeedbackDelay(delayTime);
+
+
+		//connect it up
+		this.connectLeft(this.leftDelay);
+		this.connectRight(this.rightDelay);
+
+		//disconnect the feedback lines to connect them to the other delay
+		// http://jvzaudio.files.wordpress.com/2011/04/delay-f43.gif
+		this.leftDelay.feedback.disconnect();
+		this.rightDelay.feedback.disconnect();
+		this.leftDelay.feedback.connect(this.rightDelay.effectSend);
+		this.rightDelay.feedback.connect(this.leftDelay.effectSend);
+
+		//initial vals;
+		this.setDelayTime(delayTime);
+	}
+
+	Tone.extend(Tone.PingPongDelay, Tone.StereoSplit);
+
+	//@param {number} delayTime
+	Tone.PingPongDelay.prototype.setDelayTime = function(delayTime){
+		this.leftDelay.setDelayTime(delayTime);
+		this.rightDelay.setDelayTime(delayTime * 2);
+	}
+
+	//@param {number} feedback (0 - 1)
+	Tone.PingPongDelay.prototype.setFeedback = function(feedback){
+		this.leftDelay.setFeedback(feedback);
+		this.rightDelay.setFeedback(feedback);
+	}
+
+	//@param {number} wet (0 - 1)
+	Tone.PingPongDelay.prototype.setWet = function(wet){
+		this.leftDelay.setWet(wet);
+		this.rightDelay.setWet(wet);
+	}
+
+	//@param {number} dry (0 - 1)
+	Tone.PingPongDelay.prototype.setDry = function(dry){
+		this.leftDelay.setDry(dry);
+		this.rightDelay.setDry(dry);
+	}
+
+	return Tone.PingPongDelay;
+});
+
+define('Tone/instrument/MonoSynth',["Tone/core/Tone", "Tone/component/Envelope", "Tone/source/Oscillator"], function(Tone){
+
+
+	Tone.MonoSynth = function(){
+		//one oscillator
+		this.oscillator = this.context.createOscillator();
+		this.glideTime = .01;
+		this.filterEnvelope = new Tone.Envelope();
+	}
+
+	return Tone.MonoSynth;
+});
+///////////////////////////////////////////////////////////////////////////////
+//
+//  AUDIO PLAYER
+//
+///////////////////////////////////////////////////////////////////////////////
+
+define('Tone/source/Player',["Tone/core/Tone"], function(Tone){
+
+	Tone.Player = function(url){
+		//extend Unit
+		Tone.call(this);
+
+		//player vars
+		this.url = url;
+		this.source = null;
+		this.buffer = null;
+
+		this.onended = function(){};
+	}
+
+	Tone.extend(Tone.Player, Tone);
+
+	//makes an xhr for the buffer at the url
+	//invokes the callback at the end
+	//@param {function(Tone.Player)} callback
+	Tone.Player.prototype.load = function(callback){
+		if (!this.buffer){
+			var request = new XMLHttpRequest();
+			request.open('GET', this.url, true);
+			request.responseType = 'arraybuffer';
+			// decode asynchronously
+			var self = this;
+			request.onload = function() {
+				self.context.decodeAudioData(request.response, function(buff) {
+					self.buffer = buff;
+					if (callback){
+						callback(self);
+					}
+				});
+			}
+			//send the request
+			request.send();
+		} else {
+			if (callback){
+				callback(this);
+			}
+		}
+	}
+
+	//play the buffer from start to finish at a time
+	Tone.Player.prototype.start = function(startTime, offset, duration, volume){
+		if (this.buffer){
+			//default args
+			startTime = this.defaultArg(startTime, this.now());
+			offset = this.defaultArg(offset, 0);
+			duration = this.defaultArg(duration, this.buffer.duration - offset);
+			volume = this.defaultArg(volume, 1);
+			//make the source
+			this.source = this.context.createBufferSource();
+			this.source.buffer = this.buffer;
+			this.source.loop = false;
+			this.source.start(this.toSeconds(startTime), this.toSeconds(offset), this.toSeconds(duration));
+			this.source.onended = this._onended.bind(this);
+			var gain = this.context.createGain();
+			gain.gain.value = volume;
+			this.chain(this.source, gain, this.output);
+		}
+	}
+
+	//play the buffer from start to finish at a time
+	Tone.Player.prototype.loop = function(startTime, loopStart, loopEnd, offset, duration, volume){
+		if (this.buffer){
+			//default args
+			startTime = this.defaultArg(startTime, this.now());
+			loopStart = this.defaultArg(loopStart, 0);
+			loopEnd = this.defaultArg(loopEnd, this.buffer.duration);
+			offset = this.defaultArg(offset, loopStart);
+			duration = this.defaultArg(duration, this.buffer.duration - offset);
+			//make/play the source
+			this.start(startTime, offset, duration, volume);
+			this.source.loop = true;
+			this.source.loopStart = this.toSeconds(loopStart);
+			this.source.loopEnd = this.toSeconds(loopEnd);
+		}
+	}
+
+	//stop playback
+	Tone.Player.prototype.stop = function(stopTime){
+		if (this.buffer && this.source){
+			stopTime = this.defaultArg(stopTime, this.now());
+			this.source.stop(this.toSeconds(stopTime));
+		}
+	}
+
+	//@returns {number} the buffer duration
+	Tone.Player.prototype.getDuration = function(){
+		if (this.buffer){
+			this.buffer.duration;
+		} else {
+			return 0;
+		}
+	}
+
+	//@param {function(Event)} callback
+	Tone.Player.prototype._onended = function(e){
+		this.onended(e);
+	}
+
+	return Tone.Player;
+});
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  SAMPLE PLAYER
+//
+//	dependencies : Tone, Player, Envelope, LFO
+///////////////////////////////////////////////////////////////////////////////
+
+define('Tone/instrument/Sampler',["Tone/core/Tone", "Tone/component/Envelope", "Tone/source/Player"], function(Tone){
+
+	Tone.Sampler = function(url){
+		Tone.call(this);
+
+		//components
+		this.player = new Tone.Player(url);
+		this.envelope = new Tone.Envelope(.1, .01, .1, 1);
+		this.filter = this.context.createBiquadFilter();
+		this.filter.type = "lowpass";
+		this.filter.Q.value = 12;
+		this.filterEnvelope = new Tone.Envelope(.4, 0, 1, .6, this.filter.frequency, 0, 1200);
+
+		//connect it up
+		this.chain(this.player, this.envelope, this.filter, this.output);
+	}
+
+	Tone.extend(Tone.Sampler, Tone);
+
+
+	//@param {function()=} callback
+	Tone.Sampler.prototype.load = function(callback){
+		this.player.load(callback);
+	}
+
+	Tone.Sampler.prototype.triggerAttack = function(startTime){
+		this.player.start(startTime);
+		this.envelope.triggerAttack(startTime);
+		this.filterEnvelope.triggerAttack(startTime);
+	}
+
+	Tone.Sampler.prototype.triggerRelease = function(stopTime){
+		stopTime = this.defaultArg(stopTime, this.now());
+		this.player.stop(stopTime + Math.max(this.envelope.release, this.filterEnvelope.release));
+		this.envelope.triggerRelease(stopTime);
+		this.filterEnvelope.triggerRelease(stopTime);
+	}
+
+	return Tone.Sampler;
+});
+define('Tone/signal/BitCrusher',["Tone/core/Tone"], function(Tone){
+
+	/**
+	 *  downsample incoming signal
+	 *  inspiration from https://github.com/jaz303/bitcrusher/blob/master/index.js
+	 *
+	 *  @constructor
+	 *  @extends {Tone}
+	 *  @param {number=} bits   
+	 *  @param {number=} frequency 
+	 */
+	Tone.BitCrusher = function(bits, frequency){
+
+		Tone.call(this);
+
+		/** 
+		 * @private 
+		 * @type {number}
+		 */
+		this._bits = this.defaultArg(bits, 8);
+		
+		/** 
+		 * @private 
+		 * @type {number}
+		 */
+		this._frequency = this.defaultArg(frequency, 0.5);
+		
+		/** 
+		 * @private 
+		 * @type {number}
+		 */
+		this._step = 2 * Math.pow(0.5, this._bits);
+		
+		/** 
+		 * @private 
+		 * @type {number}
+		 */
+		this._invStep = 1/this._step;
+		
+		/** 
+		 * @private 
+		 * @type {number}
+		 */
+		this._phasor = 0;
+		
+		/** 
+		 * @private 
+		 * @type {number}
+		 */
+		this._last = 0;
+		
+		/** 
+		 * @private 
+		 * @type {ScriptProcessorNode}
+		 */
+		this._crusher = this.context.createScriptProcessor(this.bufferSize, 1, 1);
+		this._crusher.onaudioprocess = this._audioprocess.bind(this);
+
+		//connect it up
+		this.chain(this.input, this._crusher, this.output);
+	};
+
+	Tone.extend(Tone.BitCrusher);
+
+	/**
+	 *  @private
+	 *  @param  {AudioProcessingEvent} event
+	 */
+	Tone.BitCrusher.prototype._audioprocess = function(event){
+		//cache the values used in the loop
+		var phasor = this._phasor;
+		var freq = this._frequency;
+		var invStep = this._invStep;
+		var last = this._last;
+		var step = this._step;
+		var input = event.inputBuffer.getChannelData(0);
+		var output = event.outputBuffer.getChannelData(0);
+		for (var i = 0, len = output.length; i < len; i++) {
+			phasor += freq;
+		    if (phasor >= 1) {
+		        phasor -= 1;
+		        last = step * ((input[i] * invStep) | 0 + 0.5);
+		    }
+		    output[i] = last;
+		}
+		//set the values for the next loop
+		this._phasor = phasor;
+		this._last = last;
+	};
+
+	/**
+	 *  set the bit rate
+	 *  
+	 *  @param {number} bits 
+	 */
+	Tone.BitCrusher.prototype.setBits = function(bits){
+		this._bits = bits;
+		this._step = 2 * Math.pow(0.5, this._bits);
+		this._invStep = 1/this._step;
+	};
+
+	/**
+	 *  set the frequency
+	 *  @param {number} freq 
+	 */
+	Tone.BitCrusher.prototype.setFrequency = function(freq){
+		this._frequency = freq;
+	};
+
+	return Tone.BitCrusher;
+});
+define('Tone/signal/Split',["Tone/core/Tone"], function(Tone){
+
+	/**
+	 *	split the incoming signal into left and right channels
+	 *
+	 *  the left channel is the default output
+	 *  
+	 *  @constructor
+	 *  @extends {Tone}
+	 */
+	Tone.Split = function(){
+		Tone.call(this);
+
+		/** @type {ChannelSplitterNode} */
+		this.splitter = this.context.createChannelSplitter(2);
+		/** 
+		 *  left channel output
+		 *  @alias for the default output
+		 *  @type {GainNode}
+		 */
+		this.left = this.output;
+		/**
+		 *  the right channel output
+		 *  @type {GainNode}
+		 */
+		this.right = this.context.createGain();
+		
+		//connections
+		this.input.connect(this.splitter);
+		this.splitter.connect(this.left, 1, 0);
+		this.splitter.connect(this.right, 0, 0);
+	};
+
+	Tone.extend(Tone.Split);
+
+	return Tone.Split;
+});
+///////////////////////////////////////////////////////////////////////////////
+//
+//	WEB RTC MICROPHONE
+//
+///////////////////////////////////////////////////////////////////////////////
+
+define('Tone/source/Microphone',["Tone/core/Tone"], function(Tone){
+
+	//@param {number=} inputNum
+	Tone.Microphone = function(inputNum){
+		//extend the base class
+		Tone.call(this);
+
+		//components
+		this.mediaStream = null;
+		this.stream = null;
+		this.constraints = {"audio" : true};
+		//get that option
+		var self = this;
+		MediaStreamTrack.getSources(function (media_sources) {
+			if (inputNum < media_sources.length){
+				self.constraints.audio = {
+					optional : [{ sourceId: media_sources[inputNum].id}]
+				}
+			}
+		});		
+	}
+
+	Tone.extend(Tone.Microphone, Tone);
+
+	//stop the WebRTC connection
+	Tone.Microphone.prototype.start = function(){
+		// Only get the audio stream.
+		navigator.getUserMedia(this.constraints, this._onStream.bind(this), this._onStreamError.bind(this));
+	}
+
+	//stop the WebRTC connection
+	Tone.Microphone.prototype.stop = function(){
+		if (this.stream){
+			this.stream.stop();
+		}
+	}
+
+	//when the stream is setup
+	Tone.Microphone.prototype._onStream = function(stream) {
+		this.stream = stream;
+		// Wrap a MediaStreamSourceNode around the live input stream.
+		this.mediaStream =  this.context.createMediaStreamSource(stream);
+		this.mediaStream.connect(this.output);
+	};
+
+	//on error
+	Tone.Microphone.prototype._onStreamError = function(e) {
+		console.error(e);
+	};
+
+	//polyfill
+	navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia 
+		|| navigator.mozGetUserMedia || navigator.msGetUserMedia;
+
+	return Tone.Microphone;
+});
+///////////////////////////////////////////////////////////////////////////////
+//
+//  NOISE
+//
+///////////////////////////////////////////////////////////////////////////////
+define('Tone/source/Noise',["Tone/core/Tone"], function(Tone){
+
+    //@param {string} type the noise type
+    Tone.Noise = function(type){
+    	//extend Unit
+    	Tone.call(this);
+
+    	//components
+    	this.jsNode = this.context.createScriptProcessor(this.bufferSize, 0, 1);
+
+    	//connections
+        this.jsNode.connect(this.output);
+
+    	this.setType(this.defaultArg(type, "white"));
+    }
+
+    Tone.extend(Tone.Noise, Tone);
+
+    //@param {string} type ('white', 'pink', 'brown')
+    Tone.Noise.prototype.setType = function(type){
+    	switch (type){
+    		case "white" : 
+    			this.jsNode.onaudioprocess = this._whiteNoise.bind(this);
+    			break;
+    		case "pink" : 
+    			this.jsNode.onaudioprocess = this._pinkNoise.bind(this);
+    			break;
+    		case "brown" : 
+    			this.jsNode.onaudioprocess = this._brownNoise.bind(this);
+    			break;
+    		default : 
+    			this.jsNode.onaudioprocess = this._whiteNoise.bind(this);
+    	}
+    }
+
+    //modified from http://noisehack.com/generate-noise-web-audio-api/
+    Tone.Noise.prototype._pinkNoise = (function() {
+        var b0, b1, b2, b3, b4, b5, b6;
+        b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;
+        return function(e) {
+            var bufferSize = this.jsNode.bufferSize;
+            var output = e.outputBuffer.getChannelData(0);
+            for (var i = 0; i < bufferSize; 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;
+                output[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;
+                output[i] *= 0.11; // (roughly) compensate for gain
+                b6 = white * 0.115926;
+            }
+        }
+    })();
+
+    //modified from http://noisehack.com/generate-noise-web-audio-api/
+    Tone.Noise.prototype._brownNoise = (function() {
+        var lastOut = 0.0;
+        return function(e) {
+            var bufferSize = this.jsNode.bufferSize;
+            var output = e.outputBuffer.getChannelData(0);
+            for (var i = 0; i < bufferSize; i++) {
+                var white = Math.random() * 2 - 1;
+                output[i] = (lastOut + (0.02 * white)) / 1.02;
+                lastOut = output[i];
+                output[i] *= 3.5; // (roughly) compensate for gain
+            }
+        }
+        return node;
+    })();
+
+    //modified from http://noisehack.com/generate-noise-web-audio-api/
+    Tone.Noise.prototype._whiteNoise = function(e){
+        var bufferSize = this.jsNode.bufferSize;
+        var output = e.outputBuffer.getChannelData(0);
+        for (var i = 0; i < bufferSize; i++) {
+            output[i] = Math.random() * 2 - 1;
+        }
+    }
+
+    return Tone.Noise;
+});
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:20 GMT-0400 (EDT) +
+ + + + + diff --git a/doc/global.html b/doc/global.html new file mode 100644 index 00000000..81adcb06 --- /dev/null +++ b/doc/global.html @@ -0,0 +1,233 @@ + + + + + JSDoc: Global + + + + + + + + + + +
+ +

Global

+ + + + + +
+ +
+

+ +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + +

Members

+ +
+ +
+

for the default output :GainNode

+ + +
+
+ +
+ left channel output +
+ + + +
Type:
+
    +
  • + +GainNode + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

{GainNode}

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 00000000..f4b10b58 --- /dev/null +++ b/doc/index.html @@ -0,0 +1,148 @@ + + + + + JSDoc: Index + + + + + + + + + + +
+ +

Index

+ + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + +
+ +
+

+ Tone.js +

+ +
+ +
+
+ + + + +
buses are another way of routing audio + + augments Tone.prototype to include send and recieve
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.2 on Wed Jun 18 2014 17:36:21 GMT-0400 (EDT) +
+ + + + + \ No newline at end of file diff --git a/doc/scripts/linenumber.js b/doc/scripts/linenumber.js new file mode 100644 index 00000000..613865d0 --- /dev/null +++ b/doc/scripts/linenumber.js @@ -0,0 +1,17 @@ +(function() { + var counter = 0; + var numbered; + var source = document.getElementsByClassName('prettyprint source'); + + if (source && source[0]) { + source = source[0].getElementsByTagName('code')[0]; + + numbered = source.innerHTML.split('\n'); + numbered = numbered.map(function(item) { + counter++; + return '' + item; + }); + + source.innerHTML = numbered.join('\n'); + } +})(); diff --git a/doc/scripts/prettify/Apache-License-2.0.txt b/doc/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/doc/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/doc/scripts/prettify/lang-css.js b/doc/scripts/prettify/lang-css.js new file mode 100644 index 00000000..041e1f59 --- /dev/null +++ b/doc/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/doc/scripts/prettify/prettify.js b/doc/scripts/prettify/prettify.js new file mode 100644 index 00000000..eef5ad7e --- /dev/null +++ b/doc/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p